'use client'

import { useState } from 'react'
import { apiFetch } from '@/lib/api'
import { useDashboardI18n } from '@/components/I18nProvider'
import VehicleConditionSheet from './VehicleConditionSheet'

type InspectionType = 'CHECKIN' | 'CHECKOUT'
type FuelLevel = 'FULL' | 'SEVEN_EIGHTHS' | 'THREE_QUARTERS' | 'FIVE_EIGHTHS' | 'HALF' | 'THREE_EIGHTHS' | 'QUARTER' | 'ONE_EIGHTH' | 'EMPTY'
type DamageType = 'SCRATCH' | 'DENT' | 'CRACK' | 'CHIP' | 'MISSING' | 'STAIN' | 'OTHER'
type DamageSeverity = 'MINOR' | 'MODERATE' | 'MAJOR'

export interface DamagePoint {
  id?: string
  viewType: 'TOP' | 'FRONT' | 'REAR' | 'LEFT' | 'RIGHT'
  x: number
  y: number
  damageType: DamageType
  severity: DamageSeverity
  description?: string | null
  isPreExisting: boolean
}

export interface DamageInspection {
  id: string
  type: InspectionType
  mileage: number | null
  fuelLevel: FuelLevel
  fuelCharge: number | null
  generalCondition: string | null
  employeeNotes: string | null
  customerAgreed: boolean
  damagePoints: DamagePoint[]
}

const fuelLevels: FuelLevel[] = ['FULL', 'SEVEN_EIGHTHS', 'THREE_QUARTERS', 'FIVE_EIGHTHS', 'HALF', 'THREE_EIGHTHS', 'QUARTER', 'ONE_EIGHTH', 'EMPTY']
const damageTypes: DamageType[] = ['SCRATCH', 'DENT', 'CRACK', 'CHIP', 'MISSING', 'STAIN', 'OTHER']
const severityColors: Record<DamageSeverity, string> = {
  MINOR: '#f59e0b',
  MODERATE: '#f97316',
  MAJOR: '#dc2626',
}

export function pointKey(point: Pick<DamagePoint, 'viewType' | 'x' | 'y' | 'damageType' | 'severity'>) {
  return `${point.viewType}:${point.x.toFixed(2)}:${point.y.toFixed(2)}:${point.damageType}:${point.severity}`
}


export function comparisonPointsForCheckout(initialInspection: DamageInspection | null | undefined, comparisonPoints: DamagePoint[]): DamagePoint[] {
  const storedPreExistingPoints = initialInspection?.damagePoints?.filter((point) => point.isPreExisting) ?? []
  return [...comparisonPoints, ...storedPreExistingPoints].filter((point, index, all) => all.findIndex((item) => pointKey(item) === pointKey(point)) === index)
}

export function editableDamagePointsForInspection(type: InspectionType, initialInspection: DamageInspection | null | undefined): DamagePoint[] {
  const points = initialInspection?.damagePoints ?? []
  return type === 'CHECKOUT' ? points.filter((point) => !point.isPreExisting) : points
}

export function buildInspectionSavePayload(inspection: DamageInspection, overlayComparisonPoints: DamagePoint[]) {
  const payloadPoints = [
    ...overlayComparisonPoints.map(({ viewType, x, y, damageType, severity, description }) => ({
      viewType,
      x,
      y,
      damageType,
      severity,
      ...(description ? { description } : {}),
      isPreExisting: true,
    })),
    ...inspection.damagePoints.map(({ viewType, x, y, damageType, severity, description, isPreExisting }) => ({
      viewType,
      x,
      y,
      damageType,
      severity,
      ...(description ? { description } : {}),
      isPreExisting,
    })),
  ]

  return {
    ...(inspection.mileage !== null ? { mileage: inspection.mileage } : {}),
    fuelLevel: inspection.fuelLevel,
    ...(inspection.fuelCharge !== null ? { fuelCharge: inspection.fuelCharge } : {}),
    ...(inspection.generalCondition ? { generalCondition: inspection.generalCondition } : {}),
    ...(inspection.employeeNotes ? { employeeNotes: inspection.employeeNotes } : {}),
    customerAgreed: inspection.customerAgreed,
    damagePoints: payloadPoints,
  }
}

export default function DamageInspectionCard({
  reservationId,
  type,
  initialInspection,
  comparisonPoints = [],
  editable = true,
  readOnlyMessage,
  onSaved,
}: {
  reservationId: string
  type: InspectionType
  initialInspection?: DamageInspection | null
  comparisonPoints?: DamagePoint[]
  editable?: boolean
  readOnlyMessage?: string | null
  onSaved: (inspection: DamageInspection) => void
}) {
  const { dict } = useDashboardI18n()
  const r = dict.reservations
  const overlayComparisonPoints = type === 'CHECKOUT'
    ? comparisonPointsForCheckout(initialInspection, comparisonPoints)
    : []

  const [inspection, setInspection] = useState<DamageInspection>({
    id: initialInspection?.id ?? `${type.toLowerCase()}-draft`,
    type,
    mileage: initialInspection?.mileage ?? null,
    fuelLevel: initialInspection?.fuelLevel ?? 'FULL',
    fuelCharge: initialInspection?.fuelCharge ?? null,
    generalCondition: initialInspection?.generalCondition ?? '',
    employeeNotes: initialInspection?.employeeNotes ?? '',
    customerAgreed: initialInspection?.customerAgreed ?? false,
    damagePoints: editableDamagePointsForInspection(type, initialInspection),
  })
  const [damageType, setDamageType] = useState<DamageType>('SCRATCH')
  const [severity, setSeverity] = useState<DamageSeverity>('MINOR')
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function saveInspection() {
    setSaving(true)
    setError(null)
    try {
      const payload = buildInspectionSavePayload(inspection, overlayComparisonPoints)

      const result = await apiFetch<DamageInspection>(`/reservations/${reservationId}/inspections/${type.toLowerCase()}`, {
        method: 'PUT',
        body: JSON.stringify(payload),
      })
      setInspection({
        ...result,
        damagePoints: type === 'CHECKOUT'
          ? result.damagePoints.filter((point) => !point.isPreExisting)
          : result.damagePoints,
      })
      onSaved(result)
    } catch (err: any) {
      setError(err.message ?? r.failedSaveInspection)
    } finally {
      setSaving(false)
    }
  }

  function addDamagePoint(viewType: DamagePoint['viewType'], x: number, y: number) {
    setInspection((current) => ({
      ...current,
      damagePoints: [
        ...current.damagePoints,
        { viewType, x, y, damageType, severity, description: '', isPreExisting: type === 'CHECKIN' },
      ],
    }))
  }

  function removePoint(index: number) {
    setInspection((current) => ({
      ...current,
      damagePoints: current.damagePoints.filter((_, i) => i !== index),
    }))
  }

  return (
    <div className="card p-6">
      <div className="flex items-start justify-between gap-4">
        <div>
          <h3 className="text-base font-semibold text-slate-900">{r.inspectionCardTitle(type)}</h3>
          <p className="mt-1 text-sm text-slate-500">{r.inspectionSubtitle}</p>
        </div>
        <button onClick={saveInspection} disabled={saving || !editable} className="btn-primary">
          {saving ? r.savingInspection : r.saveInspection}
        </button>
      </div>

      {error && <div className="mt-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">{error}</div>}
      {!editable && readOnlyMessage && (
        <div className="mt-4 rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600">
          {readOnlyMessage}
        </div>
      )}

      <div className="mt-5 grid gap-6 xl:grid-cols-[1.1fr_0.9fr]">
        <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4">
          <div className="mb-3 flex flex-wrap items-center gap-2 text-xs">
            {damageTypes.map((option) => (
              <button
                key={option}
                type="button"
                onClick={() => setDamageType(option)}
                disabled={!editable}
                className={`rounded-full px-3 py-1.5 font-semibold ${damageType === option ? 'bg-blue-700 text-white' : 'bg-white text-slate-600'}`}
              >
                {r.damageTypeLabels[option]}
              </button>
            ))}
          </div>
          <div className="mb-4 flex flex-wrap items-center gap-2 text-xs">
            {(Object.keys(severityColors) as DamageSeverity[]).map((option) => (
              <button
                key={option}
                type="button"
                onClick={() => setSeverity(option)}
                disabled={!editable}
                className="rounded-full px-3 py-1.5 font-semibold text-white"
                style={{ backgroundColor: severityColors[option], opacity: severity === option ? 1 : 0.55 }}
              >
                {r.severityLabels[option]}
              </button>
            ))}
          </div>
          {type === 'CHECKOUT' && overlayComparisonPoints.length > 0 && (
            <div className="mb-4 flex flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-slate-100 px-3 py-2 text-xs text-slate-600">
              <span className="inline-flex items-center gap-2">
                <span className="h-3.5 w-3.5 rounded-full border-2 border-dashed border-slate-500 bg-white" />
                {r.inspectionCardTitle('CHECKIN')}
              </span>
              <span className="inline-flex items-center gap-2">
                <span className="h-3.5 w-3.5 rounded-full bg-blue-700" />
                {r.inspectionCardTitle('CHECKOUT')}
              </span>
            </div>
          )}

          <VehicleConditionSheet
            points={inspection.damagePoints}
            comparisonPoints={overlayComparisonPoints}
            interactive={editable}
            onAddPoint={editable ? addDamagePoint : undefined}
            className={`w-full rounded-2xl border border-slate-200 bg-white ${editable ? 'cursor-crosshair' : 'cursor-default'}`}
          />
          <p className="mt-2 text-xs text-slate-500">{r.diagramHelp}</p>
        </div>

        <div className="space-y-4">
          <div className="grid gap-4 sm:grid-cols-2">
            <div>
              <label className="mb-1.5 block text-sm font-medium text-slate-700">{r.mileageLabel}</label>
              <input
                type="number"
                className="input-field"
                value={inspection.mileage ?? ''}
                disabled={!editable}
                onChange={(e) => setInspection((cur) => ({ ...cur, mileage: e.target.value ? Number(e.target.value) : null }))}
              />
            </div>
            <div>
              <label className="mb-1.5 block text-sm font-medium text-slate-700">{r.fuelLevelLabel}</label>
              <select className="input-field" value={inspection.fuelLevel} disabled={!editable} onChange={(e) => setInspection((cur) => ({ ...cur, fuelLevel: e.target.value as FuelLevel }))}>
                {fuelLevels.map((fl) => <option key={fl} value={fl}>{r.fuelLevels[fl]}</option>)}
              </select>
            </div>
          </div>

          <div>
            <label className="mb-1.5 block text-sm font-medium text-slate-700">{r.generalConditionLabel}</label>
            <textarea className="input-field min-h-24" value={inspection.generalCondition ?? ''} disabled={!editable} onChange={(e) => setInspection((cur) => ({ ...cur, generalCondition: e.target.value }))} />
          </div>

          <div>
            <label className="mb-1.5 block text-sm font-medium text-slate-700">{r.employeeNotesLabel}</label>
            <textarea className="input-field min-h-24" value={inspection.employeeNotes ?? ''} disabled={!editable} onChange={(e) => setInspection((cur) => ({ ...cur, employeeNotes: e.target.value }))} />
          </div>

          <label className="flex items-center gap-3 text-sm font-medium text-slate-700">
            <input type="checkbox" checked={inspection.customerAgreed} disabled={!editable} onChange={(e) => setInspection((cur) => ({ ...cur, customerAgreed: e.target.checked }))} />
            {r.customerAcknowledged}
          </label>

          <div className="rounded-2xl border border-slate-200">
            <div className="border-b border-slate-200 px-4 py-3">
              <p className="text-sm font-semibold text-slate-900">{r.damageMarkersHeading}</p>
            </div>
            <div className="divide-y divide-slate-100">
              {inspection.damagePoints.map((point, index) => (
                <div key={`${point.x}-${point.y}-${index}`} className="flex items-center justify-between gap-3 px-4 py-3 text-sm">
                  <div>
                    <p className="font-medium text-slate-900">{r.damageTypeLabels[point.damageType]} · {r.severityLabels[point.severity]}</p>
                    <p className="text-xs text-slate-500">{point.viewType} · x {point.x.toFixed(1)} · y {point.y.toFixed(1)}</p>
                  </div>
                  <button type="button" onClick={() => removePoint(index)} disabled={!editable} className="rounded-full border border-slate-300 px-3 py-1 text-xs font-semibold text-slate-600 disabled:cursor-not-allowed disabled:opacity-50">
                    {r.removeMarker}
                  </button>
                </div>
              ))}
              {inspection.damagePoints.length === 0 && (
                <div className="px-4 py-6 text-sm text-slate-400">{r.noMarkers}</div>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
