import { apiClient } from './api'

export interface DeletedShot {
  id: number
  name: string
  episode_name: string
  project_id: number
  project_name: string
  deleted_at: string
  deleted_by: number
  deleted_by_name: string
  task_count: number
  submission_count: number
  attachment_count: number
  note_count: number
  review_count: number
}

export interface DeletedAsset {
  id: number
  name: string
  category: string
  project_id: number
  project_name: string
  deleted_at: string
  deleted_by: number
  deleted_by_name: string
  task_count: number
  submission_count: number
  attachment_count: number
  note_count: number
  review_count: number
}

export interface RecoveryInfo {
  shot_id?: number
  asset_id?: number
  name: string
  episode_name?: string
  project_name: string
  
  // Counts of items that will be recovered
  task_count: number
  submission_count: number
  attachment_count: number
  note_count: number
  review_count: number
  
  // Deletion information
  deleted_at: string
  deleted_by: number
  deleted_by_name: string
  
  // File status
  files_preserved: boolean
  file_count: number
}

export interface RecoveryResult {
  success: boolean
  shot_id?: number
  asset_id?: number
  name: string
  
  // Recovery results
  recovered_tasks: number
  recovered_submissions: number
  recovered_attachments: number
  recovered_notes: number
  recovered_reviews: number
  
  // Timing
  operation_duration: number
  recovered_at: string
  recovered_by: number
  
  // Errors
  errors: string[]
  warnings: string[]
}

export interface RecoveryServiceError extends Error {
  code: 'PERMISSION_DENIED' | 'ITEM_NOT_FOUND' | 'ALREADY_ACTIVE' | 'RECOVERY_FAILED' | 'NETWORK_ERROR'
  itemId?: number
  itemType?: 'shot' | 'asset'
  details?: string
}

export interface BulkRecoveryResult {
  total_items: number
  successful_recoveries: number
  failed_recoveries: number
  results: RecoveryResult[]
  errors: Array<{
    item_id: number
    item_type: 'shot' | 'asset'
    error: string
  }>
}

export interface PermanentDeleteResult {
  success: boolean
  shot_id?: number
  asset_id?: number
  name: string
  
  // Deletion results
  deleted_tasks: number
  deleted_submissions: number
  deleted_attachments: number
  deleted_notes: number
  deleted_reviews: number
  deleted_files: number
  database_records_deleted: number
  
  // Timing
  operation_duration: number
  deleted_at: string
  deleted_by: number
  
  // Errors
  errors: string[]
  warnings: string[]
}

export interface BulkPermanentDeleteResult {
  total_items: number
  successful_deletions: number
  failed_deletions: number
  deleted_items: Array<{
    id: number
    name: string
    type: 'shot' | 'asset'
  }>
  errors: Array<{
    id: number
    error: string
  }>
  files_deleted: number
  database_records_deleted: number
}

class RecoveryService {
  private handleRecoveryError(error: any, itemId?: number, itemType?: 'shot' | 'asset'): never {
    if (error.response?.status === 403) {
      const recoveryError: RecoveryServiceError = new Error('Permission denied for recovery operation') as RecoveryServiceError
      recoveryError.code = 'PERMISSION_DENIED'
      recoveryError.itemId = itemId
      recoveryError.itemType = itemType
      throw recoveryError
    }
    if (error.response?.status === 404) {
      const recoveryError: RecoveryServiceError = new Error('Item not found in recovery data') as RecoveryServiceError
      recoveryError.code = 'ITEM_NOT_FOUND'
      recoveryError.itemId = itemId
      recoveryError.itemType = itemType
      throw recoveryError
    }
    if (error.response?.status === 409) {
      const recoveryError: RecoveryServiceError = new Error('Item is already active') as RecoveryServiceError
      recoveryError.code = 'ALREADY_ACTIVE'
      recoveryError.itemId = itemId
      recoveryError.itemType = itemType
      throw recoveryError
    }
    if (error.response?.status === 500) {
      const recoveryError: RecoveryServiceError = new Error('Recovery operation failed') as RecoveryServiceError
      recoveryError.code = 'RECOVERY_FAILED'
      recoveryError.itemId = itemId
      recoveryError.itemType = itemType
      recoveryError.details = error.response?.data?.detail || 'Recovery transaction failed'
      throw recoveryError
    }
    if (!error.response) {
      const recoveryError: RecoveryServiceError = new Error('Network error during recovery operation') as RecoveryServiceError
      recoveryError.code = 'NETWORK_ERROR'
      recoveryError.itemId = itemId
      recoveryError.itemType = itemType
      throw recoveryError
    }
    throw error
  }

  async getDeletedShots(projectId?: number): Promise<DeletedShot[]> {
    try {
      const params = new URLSearchParams()
      if (projectId) {
        params.append('project_id', projectId.toString())
      }
      
      const response = await apiClient.get(`/admin/deleted-shots/?${params}`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'shot')
    }
  }

  async getDeletedAssets(projectId?: number): Promise<DeletedAsset[]> {
    try {
      const params = new URLSearchParams()
      if (projectId) {
        params.append('project_id', projectId.toString())
      }
      
      const response = await apiClient.get(`/admin/deleted-assets/?${params}`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'asset')
    }
  }

  async previewShotRecovery(shotId: number): Promise<RecoveryInfo> {
    try {
      const response = await apiClient.get(`/admin/shots/${shotId}/recovery-preview`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, shotId, 'shot')
    }
  }

  async previewAssetRecovery(assetId: number): Promise<RecoveryInfo> {
    try {
      const response = await apiClient.get(`/admin/assets/${assetId}/recovery-preview`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, assetId, 'asset')
    }
  }

  async recoverShot(shotId: number): Promise<RecoveryResult> {
    try {
      const response = await apiClient.post(`/admin/shots/${shotId}/recover`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, shotId, 'shot')
    }
  }

  async recoverAsset(assetId: number): Promise<RecoveryResult> {
    try {
      const response = await apiClient.post(`/admin/assets/${assetId}/recover`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, assetId, 'asset')
    }
  }

  async bulkRecoverShots(shotIds: number[]): Promise<BulkRecoveryResult> {
    try {
      const response = await apiClient.post('/admin/shots/bulk-recover', { shot_ids: shotIds })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'shot')
    }
  }

  async bulkRecoverAssets(assetIds: number[]): Promise<BulkRecoveryResult> {
    try {
      const response = await apiClient.post('/admin/assets/bulk-recover', { asset_ids: assetIds })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'asset')
    }
  }

  async getRecoveryStats(projectId?: number): Promise<{
    deleted_shots_count: number
    deleted_assets_count: number
    total_deleted_tasks: number
    total_deleted_files: number
    oldest_deletion_date?: string
  }> {
    try {
      const params = new URLSearchParams()
      if (projectId) {
        params.append('project_id', projectId.toString())
      }
      
      const response = await apiClient.get(`/admin/recovery-stats/?${params}`)
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error)
    }
  }

  async permanentDeleteShot(shotId: number, confirmationToken: string): Promise<PermanentDeleteResult> {
    try {
      const response = await apiClient.delete(`/admin/shots/${shotId}/permanent`, {
        data: { confirmation_token: confirmationToken }
      })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, shotId, 'shot')
    }
  }

  async permanentDeleteAsset(assetId: number, confirmationToken: string): Promise<PermanentDeleteResult> {
    try {
      const response = await apiClient.delete(`/admin/assets/${assetId}/permanent`, {
        data: { confirmation_token: confirmationToken }
      })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, assetId, 'asset')
    }
  }

  async bulkPermanentDeleteShots(shotIds: number[], confirmationToken: string): Promise<BulkPermanentDeleteResult> {
    try {
      const response = await apiClient.delete('/admin/shots/bulk-permanent', {
        data: {
          shot_ids: shotIds,
          confirmation_token: confirmationToken
        }
      })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'shot')
    }
  }

  async bulkPermanentDeleteAssets(assetIds: number[], confirmationToken: string): Promise<BulkPermanentDeleteResult> {
    try {
      const response = await apiClient.delete('/admin/assets/bulk-permanent', {
        data: {
          asset_ids: assetIds,
          confirmation_token: confirmationToken
        }
      })
      return response.data
    } catch (error: any) {
      this.handleRecoveryError(error, undefined, 'asset')
    }
  }
}

export const recoveryService = new RecoveryService()