import { apiClient } from './api'

export interface TaskStatusInfo {
  task_type: TaskType
  status: TaskStatus
  task_id?: number
  assigned_user_id?: number
}

export interface Asset {
  id: number
  name: string
  description?: string
  category: AssetCategory
  status: AssetStatus
  project_id: number
  created_at: string
  updated_at: string
  task_count: number
  task_status?: Record<string, TaskStatus>
  task_details?: TaskStatusInfo[]
  // Soft deletion fields
  deleted_at?: string | null
  deleted_by?: number | null
  deleted_by_name?: string | null
}

export interface AssetCreate {
  name: string
  description?: string
  category: AssetCategory
  status?: AssetStatus
  create_default_tasks?: boolean
  selected_task_types?: string[]
}

export interface AssetUpdate {
  name?: string
  description?: string
  category?: AssetCategory
  status?: AssetStatus
}

export enum AssetCategory {
  CHARACTERS = 'characters',
  PROPS = 'props',
  SETS = 'sets',
  VEHICLES = 'vehicles'
}

export enum AssetStatus {
  NOT_STARTED = 'not_started',
  IN_PROGRESS = 'in_progress',
  ON_HOLD = 'on_hold',
  COMPLETED = 'completed',
  APPROVED = 'approved'
}

export enum TaskType {
  // Asset tasks
  MODELING = 'modeling',
  SURFACING = 'surfacing',
  RIGGING = 'rigging',
  // Shot tasks
  LAYOUT = 'layout',
  ANIMATION = 'animation',
  SIMULATION = 'simulation',
  LIGHTING = 'lighting',
  COMPOSITING = 'compositing'
}

export enum TaskStatus {
  NOT_STARTED = 'not_started',
  IN_PROGRESS = 'in_progress',
  SUBMITTED = 'submitted',
  APPROVED = 'approved',
  RETAKE = 'retake'
}

export interface AssetDeletionInfo {
  asset_id: number
  asset_name: string
  asset_category: string
  project_name: string
  
  // Counts of items that will be marked as deleted
  task_count: number
  submission_count: number
  attachment_count: number
  note_count: number
  review_count: number
  
  // File information (preserved, not deleted)
  total_file_size: number
  file_count: number
  
  // Affected users
  affected_users: Array<{
    id: number
    name: string
    email: string
    role: string
    task_count: number
    submission_count: number
    note_count: number
    last_activity_date?: string
  }>
  
  // Timestamps
  last_activity_date?: string
  created_at: string
}

export interface AssetSoftDeletionError extends Error {
  code: 'ASSET_NOT_FOUND' | 'ALREADY_DELETED' | 'PERMISSION_DENIED' | 'TRANSACTION_FAILED'
  assetId: number
  details?: string
}

export interface AssetRecoveryError extends Error {
  code: 'ASSET_NOT_DELETED' | 'ALREADY_ACTIVE' | 'PERMISSION_DENIED' | 'RECOVERY_FAILED'
  assetId: number
  details?: string
}

class AssetService {
  async getAssets(
    projectId: number, 
    options?: {
      category?: AssetCategory
      taskStatusFilter?: string
      sortBy?: string
      sortDirection?: 'asc' | 'desc'
    }
  ): Promise<Asset[]> {
    const params = new URLSearchParams()
    params.append('project_id', projectId.toString())
    
    if (options?.category) {
      params.append('category', options.category)
    }
    if (options?.taskStatusFilter) {
      params.append('task_status_filter', options.taskStatusFilter)
    }
    if (options?.sortBy) {
      params.append('sort_by', options.sortBy)
    }
    if (options?.sortDirection) {
      params.append('sort_direction', options.sortDirection)
    }
    
    const url = `/assets/?${params}`
    console.log('AssetService - Fetching assets from:', url)
    console.log('AssetService - Project ID:', projectId)
    
    try {
      const response = await apiClient.get(url)
      console.log('AssetService - Assets response status:', response.status)
      console.log('AssetService - Assets response data:', response.data)
      return response.data
    } catch (error) {
      console.error('AssetService - Error fetching assets:', error)
      throw error
    }
  }

  async getAsset(assetId: number): Promise<Asset> {
    const response = await apiClient.get(`/assets/${assetId}`)
    return response.data
  }

  async createAsset(projectId: number, data: AssetCreate): Promise<Asset> {
    const response = await apiClient.post(`/assets/?project_id=${projectId}`, data)
    return response.data
  }

  async getDefaultTasksForCategory(category: AssetCategory, projectId?: number): Promise<string[]> {
    const params = projectId ? `?project_id=${projectId}` : ''
    const response = await apiClient.get(`/assets/default-tasks/${category}${params}`)
    return response.data
  }

  async updateAsset(assetId: number, data: AssetUpdate): Promise<Asset> {
    const response = await apiClient.put(`/assets/${assetId}`, data)
    return response.data
  }

  async getAssetDeletionInfo(assetId: number): Promise<AssetDeletionInfo> {
    try {
      const response = await apiClient.get(`/assets/${assetId}/deletion-info`)
      return response.data
    } catch (error: any) {
      if (error.response?.status === 404) {
        const deletionError: AssetSoftDeletionError = new Error('Asset not found') as AssetSoftDeletionError
        deletionError.code = 'ASSET_NOT_FOUND'
        deletionError.assetId = assetId
        throw deletionError
      }
      if (error.response?.status === 410) {
        const deletionError: AssetSoftDeletionError = new Error('Asset already deleted') as AssetSoftDeletionError
        deletionError.code = 'ALREADY_DELETED'
        deletionError.assetId = assetId
        throw deletionError
      }
      if (error.response?.status === 403) {
        const deletionError: AssetSoftDeletionError = new Error('Permission denied') as AssetSoftDeletionError
        deletionError.code = 'PERMISSION_DENIED'
        deletionError.assetId = assetId
        throw deletionError
      }
      throw error
    }
  }

  async deleteAsset(assetId: number): Promise<void> {
    try {
      await apiClient.delete(`/assets/${assetId}`)
    } catch (error: any) {
      if (error.response?.status === 404) {
        const deletionError: AssetSoftDeletionError = new Error('Asset not found') as AssetSoftDeletionError
        deletionError.code = 'ASSET_NOT_FOUND'
        deletionError.assetId = assetId
        throw deletionError
      }
      if (error.response?.status === 410) {
        const deletionError: AssetSoftDeletionError = new Error('Asset already deleted') as AssetSoftDeletionError
        deletionError.code = 'ALREADY_DELETED'
        deletionError.assetId = assetId
        throw deletionError
      }
      if (error.response?.status === 403) {
        const deletionError: AssetSoftDeletionError = new Error('Permission denied') as AssetSoftDeletionError
        deletionError.code = 'PERMISSION_DENIED'
        deletionError.assetId = assetId
        throw deletionError
      }
      if (error.response?.status === 500) {
        const deletionError: AssetSoftDeletionError = new Error('Transaction failed during deletion') as AssetSoftDeletionError
        deletionError.code = 'TRANSACTION_FAILED'
        deletionError.assetId = assetId
        deletionError.details = error.response?.data?.detail || 'Database transaction failed'
        throw deletionError
      }
      throw error
    }
  }

  async recoverAsset(assetId: number): Promise<void> {
    try {
      await apiClient.post(`/admin/assets/${assetId}/recover`)
    } catch (error: any) {
      if (error.response?.status === 404) {
        const recoveryError: AssetRecoveryError = new Error('Asset not found in recovery data') as AssetRecoveryError
        recoveryError.code = 'ASSET_NOT_DELETED'
        recoveryError.assetId = assetId
        throw recoveryError
      }
      if (error.response?.status === 409) {
        const recoveryError: AssetRecoveryError = new Error('Asset is already active') as AssetRecoveryError
        recoveryError.code = 'ALREADY_ACTIVE'
        recoveryError.assetId = assetId
        throw recoveryError
      }
      if (error.response?.status === 403) {
        const recoveryError: AssetRecoveryError = new Error('Permission denied for recovery operation') as AssetRecoveryError
        recoveryError.code = 'PERMISSION_DENIED'
        recoveryError.assetId = assetId
        throw recoveryError
      }
      if (error.response?.status === 500) {
        const recoveryError: AssetRecoveryError = new Error('Recovery operation failed') as AssetRecoveryError
        recoveryError.code = 'RECOVERY_FAILED'
        recoveryError.assetId = assetId
        recoveryError.details = error.response?.data?.detail || 'Recovery transaction failed'
        throw recoveryError
      }
      throw error
    }
  }

  async getAssetCategories(): Promise<string[]> {
    const response = await apiClient.get('/assets/categories/')
    return response.data
  }

  async getAssetTaskStatus(assetId: number): Promise<TaskStatusInfo[]> {
    const response = await apiClient.get(`/assets/${assetId}/task-status`)
    return response.data
  }
}

export const assetService = new AssetService()