import { AxiosInstance } from 'axios'
import {
  AppVersion,
  CreateVersionInput,
  UpdateVersionInput,
  UploadVersionInput,
  VersionListFilter,
  IVersionRepository,
  ParsedPackageInfo,
  Platform,
} from '@/domain'
import { apiClient, miningApiClient, it0ApiClient, AppType, getApiPrefix } from '../http/api-client'

export class VersionRepositoryImpl implements IVersionRepository {
  private client: AxiosInstance
  private apiPrefix: string

  constructor(appType: AppType = 'mobile', client?: AxiosInstance) {
    if (client) {
      this.client = client
      this.apiPrefix = '/api/v1/versions'
    } else {
      this.client = appType === 'mining' ? miningApiClient
                   : appType === 'it0' ? it0ApiClient
                   : apiClient
      this.apiPrefix = getApiPrefix(appType)
    }
  }

  async list(filter?: VersionListFilter): Promise<AppVersion[]> {
    const params = new URLSearchParams()
    if (filter?.platform) {
      params.append('platform', filter.platform)
    }
    if (filter?.includeDisabled) {
      params.append('includeDisabled', 'true')
    }

    const response = await this.client.get<AppVersion[]>(
      `${this.apiPrefix}?${params.toString()}`
    )
    return response.data
  }

  async getById(id: string): Promise<AppVersion> {
    const response = await this.client.get<AppVersion>(`${this.apiPrefix}/${id}`)
    return response.data
  }

  async create(input: CreateVersionInput): Promise<AppVersion> {
    const response = await this.client.post<AppVersion>(this.apiPrefix, input)
    return response.data
  }

  async update(id: string, input: UpdateVersionInput): Promise<AppVersion> {
    const response = await this.client.put<AppVersion>(
      `${this.apiPrefix}/${id}`,
      input
    )
    return response.data
  }

  async delete(id: string): Promise<void> {
    await this.client.delete(`${this.apiPrefix}/${id}`)
  }

  async toggle(id: string, isEnabled: boolean): Promise<void> {
    await this.client.patch(`${this.apiPrefix}/${id}/toggle`, { isEnabled })
  }

  async upload(input: UploadVersionInput): Promise<AppVersion> {
    const formData = new FormData()
    formData.append('file', input.file)
    // Backend expects uppercase platform (ANDROID, IOS)
    formData.append('platform', input.platform.toUpperCase())
    formData.append('versionName', input.versionName)
    formData.append('buildNumber', input.buildNumber)
    formData.append('isForceUpdate', String(input.isForceUpdate ?? false))

    if (input.changelog) {
      formData.append('changelog', input.changelog)
    }
    if (input.minOsVersion) {
      formData.append('minOsVersion', input.minOsVersion)
    }
    if (input.releaseDate) {
      formData.append('releaseDate', input.releaseDate)
    }

    const response = await this.client.post<AppVersion>(
      `${this.apiPrefix}/upload`,
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        timeout: 300000, // 5 minutes for large file uploads
      }
    )
    return response.data
  }

  async parsePackage(file: File, platform: Platform): Promise<ParsedPackageInfo> {
    const formData = new FormData()
    formData.append('file', file)
    // Backend expects uppercase platform (ANDROID, IOS)
    formData.append('platform', platform.toUpperCase())

    const response = await this.client.post<ParsedPackageInfo>(
      `${this.apiPrefix}/parse`,
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        timeout: 120000, // 2 minutes for parsing
      }
    )
    return response.data
  }
}

// Pre-created repository instances for all apps
export const versionRepository = new VersionRepositoryImpl('mobile')
export const miningVersionRepository = new VersionRepositoryImpl('mining')
export const it0VersionRepository = new VersionRepositoryImpl('it0')

// Factory function to get repository by app type
export function getVersionRepository(appType: AppType): VersionRepositoryImpl {
  switch (appType) {
    case 'mining': return miningVersionRepository
    case 'it0': return it0VersionRepository
    default: return versionRepository
  }
}
