import { useState } from 'react';
import {
  Button,
  Divider,
  FileInput,
  Group,
  Modal,
  NumberInput,
  Select,
  Switch,
  Textarea,
} from '@mantine/core';
import { Upload } from 'lucide-react';

import { useMutation } from '@tanstack/react-query';

import { api } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
import {
  INSPECTION_REPORT_TYPES,
  INSPECTION_STATUSES,
  type InspectionReportType,
  type InspectionResultStatus,
} from '@/types/warehouse';
import { extractErrorMessage } from './options';

interface InspectionReportModalProps {
  opened: boolean;
  onClose: () => void;
  inventoryId: string | null;
}

const REPORT_TYPE_LABELS: Record<InspectionReportType, string> = {
  INSPECTION: 'Inspection',
  DAMAGE: 'Damage',
  WEIGHT_LOSS: 'Weight loss',
  MISSING_ITEM: 'Missing item',
  GENERAL: 'General',
};

const STATUS_LABELS: Record<InspectionResultStatus, string> = {
  PASSED: 'Passed',
  FAILED: 'Failed',
  NEEDS_REVIEW: 'Needs review',
};

/** Batch 4.5 — record an inspection / damage report with optional image upload. */
export function InspectionReportModal({ opened, onClose, inventoryId }: InspectionReportModalProps) {
  const { toast } = useToast();
  const createReport = useMutation(
    api.warehouses.createInspectionReport.mutationOptions(),
  );
  const uploadAttachments = useMutation(
    api.warehouses.uploadInspectionAttachments.mutationOptions(),
  );

  const [reportType, setReportType] = useState<InspectionReportType>('INSPECTION');
  const [inspectionStatus, setInspectionStatus] = useState<InspectionResultStatus>('PASSED');
  const [hasDamage, setHasDamage] = useState(false);
  const [damageDescription, setDamageDescription] = useState('');
  const [hasWeightLoss, setHasWeightLoss] = useState(false);
  const [expectedWeight, setExpectedWeight] = useState<number | ''>('');
  const [actualWeight, setActualWeight] = useState<number | ''>('');
  const [hasMissingItems, setHasMissingItems] = useState(false);
  const [missingItemsDescription, setMissingItemsDescription] = useState('');
  const [remarks, setRemarks] = useState('');
  const [files, setFiles] = useState<File[]>([]);

  const submitting = createReport.isPending || uploadAttachments.isPending;

  const reset = () => {
    setReportType('INSPECTION');
    setInspectionStatus('PASSED');
    setHasDamage(false);
    setDamageDescription('');
    setHasWeightLoss(false);
    setExpectedWeight('');
    setActualWeight('');
    setHasMissingItems(false);
    setMissingItemsDescription('');
    setRemarks('');
    setFiles([]);
  };

  const handleSubmit = async () => {
    if (!inventoryId) return;
    try {
      const report = await createReport.mutateAsync({
        inventoryId,
        payload: {
          reportType,
          inspectionStatus,
          hasDamage,
          damageDescription: damageDescription.trim() || undefined,
          hasWeightLoss,
          expectedWeight: expectedWeight === '' ? undefined : Number(expectedWeight),
          actualWeight: actualWeight === '' ? undefined : Number(actualWeight),
          hasMissingItems,
          missingItemsDescription: missingItemsDescription.trim() || undefined,
          remarks: remarks.trim() || undefined,
        },
      });

      if (files.length > 0) {
        await uploadAttachments.mutateAsync({ reportId: report.id, files });
      }

      toast({ title: 'Inspection report saved' });
      reset();
      onClose();
    } catch (error) {
      toast({ variant: 'destructive', title: 'Save failed', description: extractErrorMessage(error) });
    }
  };

  return (
    <Modal opened={opened} onClose={onClose} title="Inspection / Report" centered size="lg">
      <Group grow>
        <Select
          label="Report type"
          data={INSPECTION_REPORT_TYPES.map((t) => ({ value: t, label: REPORT_TYPE_LABELS[t] }))}
          value={reportType}
          onChange={(v) => setReportType((v as InspectionReportType) ?? 'INSPECTION')}
          allowDeselect={false}
        />
        <Select
          label="Inspection status"
          data={INSPECTION_STATUSES.map((s) => ({ value: s, label: STATUS_LABELS[s] }))}
          value={inspectionStatus}
          onChange={(v) => setInspectionStatus((v as InspectionResultStatus) ?? 'PASSED')}
          allowDeselect={false}
        />
      </Group>

      <Divider my="md" label="Damage" labelPosition="left" />
      <Switch
        label="Has damage"
        checked={hasDamage}
        onChange={(e) => setHasDamage(e.currentTarget.checked)}
        color="orange"
      />
      {hasDamage && (
        <Textarea
          mt="xs"
          label="Damage description"
          value={damageDescription}
          onChange={(e) => setDamageDescription(e.currentTarget.value)}
        />
      )}

      <Divider my="md" label="Weight loss" labelPosition="left" />
      <Switch
        label="Has weight loss"
        checked={hasWeightLoss}
        onChange={(e) => setHasWeightLoss(e.currentTarget.checked)}
        color="orange"
      />
      {hasWeightLoss && (
        <Group grow mt="xs">
          <NumberInput
            label="Expected weight (kg)"
            min={0}
            value={expectedWeight}
            onChange={(v) => setExpectedWeight(v === '' ? '' : Number(v))}
          />
          <NumberInput
            label="Actual weight (kg)"
            min={0}
            value={actualWeight}
            onChange={(v) => setActualWeight(v === '' ? '' : Number(v))}
          />
        </Group>
      )}

      <Divider my="md" label="Missing items" labelPosition="left" />
      <Switch
        label="Has missing items"
        checked={hasMissingItems}
        onChange={(e) => setHasMissingItems(e.currentTarget.checked)}
        color="orange"
      />
      {hasMissingItems && (
        <Textarea
          mt="xs"
          label="Missing items description"
          value={missingItemsDescription}
          onChange={(e) => setMissingItemsDescription(e.currentTarget.value)}
        />
      )}

      <Divider my="md" />
      <Textarea
        label="Remarks"
        value={remarks}
        onChange={(e) => setRemarks(e.currentTarget.value)}
      />

      <FileInput
        mt="md"
        label="Images / documents"
        placeholder="Upload jpg, png or pdf"
        accept="image/jpeg,image/png,application/pdf"
        leftSection={<Upload size={16} />}
        multiple
        value={files}
        onChange={setFiles}
        clearable
      />

      <Group justify="flex-end" mt="lg">
        <Button variant="default" onClick={onClose} disabled={submitting}>
          Cancel
        </Button>
        <Button color="edr-green" onClick={handleSubmit} loading={submitting} disabled={!inventoryId}>
          Save report
        </Button>
      </Group>
    </Modal>
  );
}
