import apiClient from './client'

export interface BackupJob {
  id: string
  job_id: number
  job_name: string
  client_name: string
  job_type: string
  job_level: string
  status: 'Running' | 'Completed' | 'Failed' | 'Canceled' | 'Waiting'
  bytes_written: number
  files_written: number
  duration_seconds?: number
  started_at?: string
  ended_at?: string
  error_message?: string
  storage_name?: string
  pool_name?: string
  volume_name?: string
  created_at: string
  updated_at: string
}

export interface ListJobsResponse {
  jobs: BackupJob[]
  total: number
  limit: number
  offset: number
}

export interface ListJobsParams {
  status?: string
  job_type?: string
  client_name?: string
  job_name?: string
  limit?: number
  offset?: number
}

export interface CreateJobRequest {
  job_name: string
  client_name: string
  job_type: string
  job_level: string
  storage_name?: string
  pool_name?: string
}

export interface BackupClient {
  client_id: number
  name: string
  uname?: string
  enabled: boolean
  category?: 'File' | 'Database' | 'Virtual'
  auto_prune?: boolean
  file_retention?: number
  job_retention?: number
  last_backup_at?: string
  total_jobs?: number
  total_bytes?: number
  status?: 'online' | 'offline'
}

export interface ListClientsResponse {
  clients: BackupClient[]
  total: number
}

export interface ListClientsParams {
  enabled?: boolean
  search?: string
  category?: 'File' | 'Database' | 'Virtual'
}

export interface PoolStats {
  name: string
  used_bytes: number
  total_bytes: number
  usage_percent: number
}

export interface DashboardStats {
  director_status: string
  director_uptime: string
  last_job?: BackupJob
  active_jobs_count: number
  default_pool?: PoolStats
}

export const backupAPI = {
  listJobs: async (params?: ListJobsParams): Promise<ListJobsResponse> => {
    const queryParams = new URLSearchParams()
    if (params?.status) queryParams.append('status', params.status)
    if (params?.job_type) queryParams.append('job_type', params.job_type)
    if (params?.client_name) queryParams.append('client_name', params.client_name)
    if (params?.job_name) queryParams.append('job_name', params.job_name)
    if (params?.limit) queryParams.append('limit', params.limit.toString())
    if (params?.offset) queryParams.append('offset', params.offset.toString())

    const response = await apiClient.get<ListJobsResponse>(
      `/backup/jobs${queryParams.toString() ? `?${queryParams.toString()}` : ''}`
    )
    return response.data
  },

  getJob: async (id: string): Promise<BackupJob> => {
    const response = await apiClient.get<BackupJob>(`/backup/jobs/${id}`)
    return response.data
  },

  createJob: async (data: CreateJobRequest): Promise<BackupJob> => {
    const response = await apiClient.post<BackupJob>('/backup/jobs', data)
    return response.data
  },

  executeBconsoleCommand: async (command: string): Promise<{ output: string }> => {
    const response = await apiClient.post<{ output: string }>('/backup/console/execute', { command })
    return response.data
  },

  listClients: async (params?: ListClientsParams): Promise<ListClientsResponse> => {
    const queryParams = new URLSearchParams()
    if (params?.enabled !== undefined) queryParams.append('enabled', params.enabled.toString())
    if (params?.search) queryParams.append('search', params.search)
    if (params?.category) queryParams.append('category', params.category)

    const response = await apiClient.get<ListClientsResponse>(
      `/backup/clients${queryParams.toString() ? `?${queryParams.toString()}` : ''}`
    )
    return response.data
  },

  getDashboardStats: async (): Promise<DashboardStats> => {
    const response = await apiClient.get<DashboardStats>('/backup/dashboard/stats')
    return response.data
  },

  listStoragePools: async (): Promise<{ pools: StoragePool[]; total: number }> => {
    const response = await apiClient.get<{ pools: StoragePool[]; total: number }>('/backup/storage/pools')
    return response.data
  },

  listStorageVolumes: async (poolName?: string): Promise<{ volumes: StorageVolume[]; total: number }> => {
    const queryParams = new URLSearchParams()
    if (poolName) queryParams.append('pool_name', poolName)
    const response = await apiClient.get<{ volumes: StorageVolume[]; total: number }>(
      `/backup/storage/volumes${queryParams.toString() ? `?${queryParams.toString()}` : ''}`
    )
    return response.data
  },

  listStorageDaemons: async (): Promise<{ daemons: StorageDaemon[]; total: number }> => {
    const response = await apiClient.get<{ daemons: StorageDaemon[]; total: number }>('/backup/storage/daemons')
    return response.data
  },

  createStoragePool: async (data: CreateStoragePoolRequest): Promise<StoragePool> => {
    const response = await apiClient.post<StoragePool>('/backup/storage/pools', data)
    return response.data
  },

  deleteStoragePool: async (poolId: number): Promise<void> => {
    await apiClient.delete(`/backup/storage/pools/${poolId}`)
  },

  createStorageVolume: async (data: CreateStorageVolumeRequest): Promise<StorageVolume> => {
    const response = await apiClient.post<StorageVolume>('/backup/storage/volumes', data)
    return response.data
  },

  updateStorageVolume: async (volumeId: number, data: UpdateStorageVolumeRequest): Promise<StorageVolume> => {
    const response = await apiClient.put<StorageVolume>(`/backup/storage/volumes/${volumeId}`, data)
    return response.data
  },

  deleteStorageVolume: async (volumeId: number): Promise<void> => {
    await apiClient.delete(`/backup/storage/volumes/${volumeId}`)
  },

  listMedia: async (): Promise<{ media: Media[]; total: number }> => {
    const response = await apiClient.get<{ media: Media[]; total: number }>('/backup/media')
    return response.data
  },
}

export interface CreateStoragePoolRequest {
  name: string
  pool_type?: string
  label_format?: string
  recycle?: boolean
  auto_prune?: boolean
}

export interface CreateStorageVolumeRequest {
  volume_name: string
  pool_name: string
  media_type?: string
  max_vol_bytes?: number
  vol_retention?: number
}

export interface UpdateStorageVolumeRequest {
  max_vol_bytes?: number
  vol_retention?: number
}

export interface Media {
  media_id: number
  volume_name: string
  pool_name: string
  media_type: string
  status: string
  vol_bytes: number
  max_vol_bytes: number
  vol_files: number
  last_written?: string
  recycle_count: number
  slot?: number
  in_changer?: number
  library_name?: string
}

export interface StoragePool {
  pool_id: number
  name: string
  pool_type: string
  label_format?: string
  recycle?: boolean
  auto_prune?: boolean
  volume_count: number
  used_bytes: number
  total_bytes: number
  usage_percent: number
}

export interface StorageVolume {
  volume_id: number
  media_id: number
  volume_name: string
  pool_name: string
  media_type: string
  vol_status: string
  vol_bytes: number
  max_vol_bytes: number
  vol_files: number
  vol_retention?: string
  last_written?: string
  recycle_count: number
}

export interface StorageDaemon {
  storage_id: number
  name: string
  address: string
  port: number
  device_name: string
  media_type: string
  status: string
}

