import type React from 'react'
import type {
  VendorComplianceAction,
  VendorComplianceState,
  ProcessingActivity,
  Vendor,
  ContractDocument,
  Finding,
  ControlInstance,
  ExportFormat,
} from './types'

type Dispatch = React.Dispatch<VendorComplianceAction>

const API_BASE = '/api/sdk/v1/vendor-compliance'

// ==========================================
// DATA LOADING
// ==========================================

export async function loadAllData(dispatch: Dispatch): Promise<void> {
  dispatch({ type: 'SET_LOADING', payload: true })
  dispatch({ type: 'SET_ERROR', payload: null })

  try {
    const [
      activitiesRes,
      vendorsRes,
      contractsRes,
      findingsRes,
      controlsRes,
      controlInstancesRes,
    ] = await Promise.all([
      fetch(`${API_BASE}/processing-activities`),
      fetch(`${API_BASE}/vendors`),
      fetch(`${API_BASE}/contracts`),
      fetch(`${API_BASE}/findings`),
      fetch(`${API_BASE}/controls`),
      fetch(`${API_BASE}/control-instances`),
    ])

    if (activitiesRes.ok) {
      const data = await activitiesRes.json()
      dispatch({ type: 'SET_PROCESSING_ACTIVITIES', payload: data.data || [] })
    }

    if (vendorsRes.ok) {
      const data = await vendorsRes.json()
      dispatch({ type: 'SET_VENDORS', payload: data.data || [] })
    }

    if (contractsRes.ok) {
      const data = await contractsRes.json()
      dispatch({ type: 'SET_CONTRACTS', payload: data.data || [] })
    }

    if (findingsRes.ok) {
      const data = await findingsRes.json()
      dispatch({ type: 'SET_FINDINGS', payload: data.data || [] })
    }

    if (controlsRes.ok) {
      const data = await controlsRes.json()
      dispatch({ type: 'SET_CONTROLS', payload: data.data || [] })
    }

    if (controlInstancesRes.ok) {
      const data = await controlInstancesRes.json()
      dispatch({ type: 'SET_CONTROL_INSTANCES', payload: data.data || [] })
    }
  } catch (error) {
    console.error('Failed to load vendor compliance data:', error)
    dispatch({
      type: 'SET_ERROR',
      payload: 'Fehler beim Laden der Daten',
    })
  } finally {
    dispatch({ type: 'SET_LOADING', payload: false })
  }
}

// ==========================================
// PROCESSING ACTIVITIES ACTIONS
// ==========================================

export async function apiCreateProcessingActivity(
  dispatch: Dispatch,
  data: Omit<ProcessingActivity, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>
): Promise<ProcessingActivity> {
  const response = await fetch(`${API_BASE}/processing-activities`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Erstellen der Verarbeitungstaetigkeit')
  }

  const result = await response.json()
  const activity = result.data

  dispatch({ type: 'ADD_PROCESSING_ACTIVITY', payload: activity })

  return activity
}

export async function apiUpdateProcessingActivity(
  dispatch: Dispatch,
  id: string,
  data: Partial<ProcessingActivity>
): Promise<void> {
  const response = await fetch(`${API_BASE}/processing-activities/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Aktualisieren der Verarbeitungstaetigkeit')
  }

  dispatch({ type: 'UPDATE_PROCESSING_ACTIVITY', payload: { id, data } })
}

export async function apiDeleteProcessingActivity(
  dispatch: Dispatch,
  id: string
): Promise<void> {
  const response = await fetch(`${API_BASE}/processing-activities/${id}`, {
    method: 'DELETE',
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Loeschen der Verarbeitungstaetigkeit')
  }

  dispatch({ type: 'DELETE_PROCESSING_ACTIVITY', payload: id })
}

export async function apiDuplicateProcessingActivity(
  dispatch: Dispatch,
  state: VendorComplianceState,
  id: string
): Promise<ProcessingActivity> {
  const original = state.processingActivities.find((a) => a.id === id)
  if (!original) {
    throw new Error('Verarbeitungstaetigkeit nicht gefunden')
  }

  const { id: _id, vvtId: _vvtId, createdAt: _createdAt, updatedAt: _updatedAt, tenantId: _tenantId, ...rest } = original

  const newActivity = await apiCreateProcessingActivity(dispatch, {
    ...rest,
    vvtId: '', // Will be generated by backend
    name: {
      de: `${original.name.de} (Kopie)`,
      en: `${original.name.en} (Copy)`,
    },
    status: 'DRAFT',
  })

  return newActivity
}

// ==========================================
// VENDOR ACTIONS
// ==========================================

export async function apiCreateVendor(
  dispatch: Dispatch,
  data: Omit<Vendor, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>
): Promise<Vendor> {
  const response = await fetch(`${API_BASE}/vendors`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Erstellen des Vendors')
  }

  const result = await response.json()
  const vendor = result.data

  dispatch({ type: 'ADD_VENDOR', payload: vendor })

  return vendor
}

export async function apiUpdateVendor(
  dispatch: Dispatch,
  id: string,
  data: Partial<Vendor>
): Promise<void> {
  const response = await fetch(`${API_BASE}/vendors/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Aktualisieren des Vendors')
  }

  dispatch({ type: 'UPDATE_VENDOR', payload: { id, data } })
}

export async function apiDeleteVendor(
  dispatch: Dispatch,
  id: string
): Promise<void> {
  const response = await fetch(`${API_BASE}/vendors/${id}`, {
    method: 'DELETE',
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Loeschen des Vendors')
  }

  dispatch({ type: 'DELETE_VENDOR', payload: id })
}

// ==========================================
// CONTRACT ACTIONS
// ==========================================

export async function apiUploadContract(
  dispatch: Dispatch,
  state: VendorComplianceState,
  vendorId: string,
  file: File,
  metadata: Partial<ContractDocument>
): Promise<ContractDocument> {
  const formData = new FormData()
  formData.append('file', file)
  formData.append('vendorId', vendorId)
  formData.append('metadata', JSON.stringify(metadata))

  const response = await fetch(`${API_BASE}/contracts`, {
    method: 'POST',
    body: formData,
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Hochladen des Vertrags')
  }

  const result = await response.json()
  const contract = result.data

  dispatch({ type: 'ADD_CONTRACT', payload: contract })

  // Update vendor's contracts list
  const vendor = state.vendors.find((v) => v.id === vendorId)
  if (vendor) {
    dispatch({
      type: 'UPDATE_VENDOR',
      payload: {
        id: vendorId,
        data: { contracts: [...vendor.contracts, contract.id] },
      },
    })
  }

  return contract
}

export async function apiUpdateContract(
  dispatch: Dispatch,
  id: string,
  data: Partial<ContractDocument>
): Promise<void> {
  const response = await fetch(`${API_BASE}/contracts/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Aktualisieren des Vertrags')
  }

  dispatch({ type: 'UPDATE_CONTRACT', payload: { id, data } })
}

export async function apiDeleteContract(
  dispatch: Dispatch,
  state: VendorComplianceState,
  id: string
): Promise<void> {
  const contract = state.contracts.find((c) => c.id === id)

  const response = await fetch(`${API_BASE}/contracts/${id}`, {
    method: 'DELETE',
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Loeschen des Vertrags')
  }

  dispatch({ type: 'DELETE_CONTRACT', payload: id })

  // Update vendor's contracts list
  if (contract) {
    const vendor = state.vendors.find((v) => v.id === contract.vendorId)
    if (vendor) {
      dispatch({
        type: 'UPDATE_VENDOR',
        payload: {
          id: vendor.id,
          data: { contracts: vendor.contracts.filter((cId) => cId !== id) },
        },
      })
    }
  }
}

export async function apiStartContractReview(
  dispatch: Dispatch,
  contractId: string
): Promise<void> {
  dispatch({
    type: 'UPDATE_CONTRACT',
    payload: { id: contractId, data: { reviewStatus: 'IN_PROGRESS' } },
  })

  const response = await fetch(`${API_BASE}/contracts/${contractId}/review`, {
    method: 'POST',
  })

  if (!response.ok) {
    dispatch({
      type: 'UPDATE_CONTRACT',
      payload: { id: contractId, data: { reviewStatus: 'FAILED' } },
    })
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Starten der Vertragspruefung')
  }

  const result = await response.json()

  // Update contract with review results
  dispatch({
    type: 'UPDATE_CONTRACT',
    payload: {
      id: contractId,
      data: {
        reviewStatus: 'COMPLETED',
        reviewCompletedAt: new Date(),
        complianceScore: result.data.complianceScore,
      },
    },
  })

  // Add findings
  if (result.data.findings && result.data.findings.length > 0) {
    dispatch({ type: 'ADD_FINDINGS', payload: result.data.findings })
  }
}

// ==========================================
// FINDINGS ACTIONS
// ==========================================

export async function apiUpdateFinding(
  dispatch: Dispatch,
  id: string,
  data: Partial<Finding>
): Promise<void> {
  const response = await fetch(`${API_BASE}/findings/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Aktualisieren des Findings')
  }

  dispatch({ type: 'UPDATE_FINDING', payload: { id, data } })
}

export async function apiResolveFinding(
  dispatch: Dispatch,
  id: string,
  resolution: string
): Promise<void> {
  await apiUpdateFinding(dispatch, id, {
    status: 'RESOLVED',
    resolution,
    resolvedAt: new Date(),
  })
}

// ==========================================
// CONTROL ACTIONS
// ==========================================

export async function apiUpdateControlInstance(
  dispatch: Dispatch,
  id: string,
  data: Partial<ControlInstance>
): Promise<void> {
  const response = await fetch(`${API_BASE}/control-instances/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Aktualisieren des Control-Status')
  }

  dispatch({ type: 'UPDATE_CONTROL_INSTANCE', payload: { id, data } })
}

// ==========================================
// EXPORT ACTIONS
// ==========================================

export async function apiExportVVT(
  format: ExportFormat,
  activityIds?: string[]
): Promise<string> {
  const params = new URLSearchParams({ format })
  if (activityIds && activityIds.length > 0) {
    params.append('activityIds', activityIds.join(','))
  }

  const response = await fetch(`${API_BASE}/export/vvt?${params}`)

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Exportieren des VVT')
  }

  const blob = await response.blob()
  const url = URL.createObjectURL(blob)

  return url
}

export async function apiExportVendorAuditPack(
  vendorId: string,
  format: ExportFormat
): Promise<string> {
  const params = new URLSearchParams({ format, vendorId })

  const response = await fetch(`${API_BASE}/export/vendor-audit?${params}`)

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Exportieren des Vendor Audit Packs')
  }

  const blob = await response.blob()
  const url = URL.createObjectURL(blob)

  return url
}

export async function apiExportRoPA(
  format: ExportFormat
): Promise<string> {
  const params = new URLSearchParams({ format })

  const response = await fetch(`${API_BASE}/export/ropa?${params}`)

  if (!response.ok) {
    const error = await response.json()
    throw new Error(error.error || 'Fehler beim Exportieren des RoPA')
  }

  const blob = await response.blob()
  const url = URL.createObjectURL(blob)

  return url
}
