'use client';

import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Loader2, Pencil, Plus, Trash2, Wrench } from 'lucide-react';
import { toast } from 'sonner';

import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { DatePicker } from '@/components/ui/date-picker';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { PermissionGate } from '@/components/shared/permission-gate';
import { EmptyState } from '@/components/shared/empty-state';
import { useConfirmation } from '@/hooks/use-confirmation';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { formatCurrency } from '@/lib/utils/currency';
import { cn } from '@/lib/utils';

type MaintenanceCategory = 'routine' | 'repair' | 'inspection' | 'upgrade';

interface MaintenanceLog {
  id: string;
  berthId: string;
  category: MaintenanceCategory;
  description: string;
  cost: string | null;
  costCurrency: string | null;
  responsibleParty: string | null;
  /** 'YYYY-MM-DD' calendar date (postgres `date` column). */
  performedDate: string;
  photoFileIds: string[] | null;
  createdAt: string;
  updatedAt: string;
}

const CATEGORIES: MaintenanceCategory[] = ['routine', 'repair', 'inspection', 'upgrade'];

const CATEGORY_LABELS: Record<MaintenanceCategory, string> = {
  routine: 'Routine',
  repair: 'Repair',
  inspection: 'Inspection',
  upgrade: 'Upgrade',
};

const CATEGORY_TONES: Record<MaintenanceCategory, string> = {
  routine: 'bg-slate-100 text-slate-700',
  repair: 'bg-rose-100 text-rose-700',
  inspection: 'bg-blue-100 text-blue-700',
  upgrade: 'bg-emerald-100 text-emerald-700',
};

/** Render a 'YYYY-MM-DD' calendar date without a timezone shift — treat it
 *  as a wall-clock date, not an instant (else dates west of UTC render a day
 *  early). */
function formatDate(iso: string): string {
  const [y, m, d] = iso.split('-').map(Number);
  if (!y || !m || !d) return iso;
  return new Date(y, m - 1, d).toLocaleDateString();
}

export function BerthMaintenanceTab({ berthId }: { berthId: string }) {
  const qc = useQueryClient();
  const { confirm, dialog: confirmDialog } = useConfirmation();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<MaintenanceLog | null>(null);

  const { data, isLoading } = useQuery<{ data: MaintenanceLog[] }>({
    queryKey: ['berths', berthId, 'maintenance'],
    queryFn: () => apiFetch(`/api/v1/berths/${berthId}/maintenance`),
  });

  useRealtimeInvalidation({
    'berth:maintenanceAdded': [['berths', berthId, 'maintenance']],
    'berth:maintenanceUpdated': [['berths', berthId, 'maintenance']],
    'berth:maintenanceRemoved': [['berths', berthId, 'maintenance']],
  });

  const logs = data?.data ?? [];

  const deleteMutation = useMutation({
    mutationFn: (logId: string) =>
      apiFetch(`/api/v1/berths/${berthId}/maintenance/${logId}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['berths', berthId, 'maintenance'] });
      toast.success('Maintenance entry deleted.');
    },
    onError: (err) => toastError(err),
  });

  async function handleDelete(log: MaintenanceLog) {
    const ok = await confirm({
      title: 'Delete maintenance entry',
      description: `Delete the ${CATEGORY_LABELS[log.category].toLowerCase()} entry from ${formatDate(
        log.performedDate,
      )}? This cannot be undone.`,
      confirmLabel: 'Delete',
    });
    if (!ok) return;
    deleteMutation.mutate(log.id);
  }

  return (
    <div className="space-y-5">
      <div className="flex items-center justify-between">
        <h3 className="text-lg font-semibold">Maintenance log</h3>
        <PermissionGate resource="berths" action="edit">
          <Button
            size="sm"
            onClick={() => {
              setEditing(null);
              setDialogOpen(true);
            }}
          >
            <Plus className="me-1.5 h-4 w-4" aria-hidden />
            Add entry
          </Button>
        </PermissionGate>
      </div>

      {isLoading ? (
        <p className="text-sm text-muted-foreground">Loading…</p>
      ) : logs.length === 0 ? (
        <EmptyState
          icon={Wrench}
          title="No maintenance recorded"
          description="Log routine upkeep, repairs, inspections, and upgrades for this berth."
        />
      ) : (
        <ul className="space-y-2">
          {logs.map((log) => (
            <li key={log.id} className="rounded-lg border bg-background p-4">
              <div className="flex items-start justify-between gap-3">
                <div className="min-w-0 flex-1 space-y-1">
                  <div className="flex flex-wrap items-center gap-2">
                    <Badge
                      variant="outline"
                      className={cn(
                        'border-transparent text-xs font-semibold',
                        CATEGORY_TONES[log.category],
                      )}
                    >
                      {CATEGORY_LABELS[log.category]}
                    </Badge>
                    <span className="text-sm font-medium">{formatDate(log.performedDate)}</span>
                    {log.cost ? (
                      <span className="text-xs text-muted-foreground">
                        {formatCurrency(log.cost, log.costCurrency)}
                      </span>
                    ) : null}
                  </div>
                  <p className="whitespace-pre-wrap break-words text-sm text-foreground">
                    {log.description}
                  </p>
                  {log.responsibleParty ? (
                    <p className="text-xs text-muted-foreground">By {log.responsibleParty}</p>
                  ) : null}
                </div>
                <PermissionGate resource="berths" action="edit">
                  <div className="flex shrink-0 items-center gap-1">
                    <Button
                      variant="ghost"
                      size="icon"
                      className="size-8"
                      onClick={() => {
                        setEditing(log);
                        setDialogOpen(true);
                      }}
                      aria-label="Edit entry"
                    >
                      <Pencil className="size-4" aria-hidden />
                    </Button>
                    <Button
                      variant="ghost"
                      size="icon"
                      className="size-8 text-destructive hover:text-destructive"
                      onClick={() => handleDelete(log)}
                      aria-label="Delete entry"
                      disabled={deleteMutation.isPending}
                    >
                      <Trash2 className="size-4" aria-hidden />
                    </Button>
                  </div>
                </PermissionGate>
              </div>
            </li>
          ))}
        </ul>
      )}

      {/* Keyed conditional mount: a fresh form state is seeded from `editing`
          each time the dialog opens (add => key 'new', edit => key <id>). */}
      {dialogOpen && (
        <MaintenanceEntryDialog
          key={editing?.id ?? 'new'}
          berthId={berthId}
          editing={editing}
          onClose={() => setDialogOpen(false)}
        />
      )}
      {confirmDialog}
    </div>
  );
}

function MaintenanceEntryDialog({
  berthId,
  editing,
  onClose,
}: {
  berthId: string;
  editing: MaintenanceLog | null;
  onClose: () => void;
}) {
  const qc = useQueryClient();
  const isEdit = editing !== null;

  const [category, setCategory] = useState<MaintenanceCategory>(editing?.category ?? 'routine');
  const [performedDate, setPerformedDate] = useState(
    editing?.performedDate ?? new Date().toISOString().slice(0, 10),
  );
  const [description, setDescription] = useState(editing?.description ?? '');
  const [cost, setCost] = useState(editing?.cost ?? '');
  const [costCurrency, setCostCurrency] = useState(editing?.costCurrency ?? 'USD');
  const [responsibleParty, setResponsibleParty] = useState(editing?.responsibleParty ?? '');

  const mutation = useMutation({
    mutationFn: async () => {
      const body = {
        category,
        performedDate,
        description: description.trim(),
        // Empty cost clears the column (null), not 0.
        cost: cost.trim() === '' ? null : Number(cost),
        costCurrency: costCurrency.trim() || 'USD',
        responsibleParty: responsibleParty.trim() === '' ? null : responsibleParty.trim(),
      };
      if (isEdit) {
        return apiFetch(`/api/v1/berths/${berthId}/maintenance/${editing.id}`, {
          method: 'PATCH',
          body,
        });
      }
      return apiFetch(`/api/v1/berths/${berthId}/maintenance`, { method: 'POST', body });
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['berths', berthId, 'maintenance'] });
      toast.success(isEdit ? 'Maintenance entry updated.' : 'Maintenance entry added.');
      onClose();
    },
    onError: (err) => toastError(err),
  });

  const canSave = description.trim().length > 0 && performedDate.length > 0;

  return (
    <Dialog open onOpenChange={(next) => !next && onClose()}>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>{isEdit ? 'Edit maintenance entry' : 'Add maintenance entry'}</DialogTitle>
          <DialogDescription>
            Record upkeep performed on this berth: category, date, what was done, and optional cost.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3 py-1">
          <div className="grid grid-cols-2 gap-3">
            <div>
              <Label>Category</Label>
              <Select value={category} onValueChange={(v) => setCategory(v as MaintenanceCategory)}>
                <SelectTrigger className="mt-1">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {CATEGORIES.map((c) => (
                    <SelectItem key={c} value={c}>
                      {CATEGORY_LABELS[c]}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Date performed</Label>
              <div className="mt-1">
                <DatePicker value={performedDate} onChange={setPerformedDate} toDate={new Date()} />
              </div>
            </div>
          </div>

          <div>
            <Label>Description *</Label>
            <Textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={3}
              className="mt-1"
              placeholder="What was done"
            />
          </div>

          <div className="grid grid-cols-3 gap-3">
            <div className="col-span-2">
              <Label>Cost (optional)</Label>
              <Input
                type="number"
                inputMode="decimal"
                min="0"
                step="0.01"
                value={cost}
                onChange={(e) => setCost(e.target.value)}
                className="mt-1"
                placeholder="0.00"
              />
            </div>
            <div>
              <Label>Currency</Label>
              <Input
                value={costCurrency}
                onChange={(e) => setCostCurrency(e.target.value.toUpperCase())}
                maxLength={3}
                className="mt-1"
              />
            </div>
          </div>

          <div>
            <Label>Responsible party (optional)</Label>
            <Input
              value={responsibleParty}
              onChange={(e) => setResponsibleParty(e.target.value)}
              className="mt-1"
              placeholder="Contractor / staff name"
            />
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={mutation.isPending}>
            Cancel
          </Button>
          <Button onClick={() => mutation.mutate()} disabled={!canSave || mutation.isPending}>
            {mutation.isPending ? (
              <Loader2 className="me-1.5 h-3.5 w-3.5 animate-spin" aria-hidden />
            ) : null}
            {isEdit ? 'Save changes' : 'Add entry'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
