'use client';

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

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

export interface SavedTemplate {
  id: string;
  portId: string;
  kind: string;
  name: string;
  description: string | null;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  config: Record<string, any>;
}

interface Props {
  kind: 'dashboard' | 'clients' | 'berths' | 'interests' | 'sales' | 'operational';
  /** Called when the rep picks a template from the dropdown - the
   *  parent hydrates its form from the returned config. */
  onApply: (template: SavedTemplate) => void;
  /** Used by the "Save as template" toggle to capture the current
   *  dialog state when the rep checks the box. */
  currentConfig: Record<string, unknown>;
  /** When set, allow saving the current dialog state as a new
   *  template. The dialog manages the toggle + name input
   *  inline so reps don't need to leave the export flow. */
  showSave?: boolean;
}

/**
 * Reusable Saved-templates picker. Mounted at the top of both
 * dashboard / list export dialogs.
 *
 * - Dropdown lists existing templates for this port + kind.
 * - "Save as template" expands to a name field + Save button when
 *   showSave is true.
 * - Delete action sits next to the dropdown when a template is
 *   selected, so the rep can prune the list without leaving the
 *   dialog.
 */
export function SavedTemplatesPicker({ kind, onApply, currentConfig, showSave = true }: Props) {
  const qc = useQueryClient();
  const [selectedId, setSelectedId] = useState<string>('');
  const [saving, setSaving] = useState(false);
  const [saveName, setSaveName] = useState('');
  const [saveOpen, setSaveOpen] = useState(false);

  const { data, isLoading } = useQuery<{ data: SavedTemplate[] }>({
    queryKey: ['report-templates', kind],
    queryFn: () =>
      apiFetch<{ data: SavedTemplate[] }>(
        `/api/v1/reports/templates?kind=${encodeURIComponent(kind)}`,
      ),
    staleTime: 30_000,
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      await apiFetch(`/api/v1/reports/templates/${id}`, { method: 'DELETE' });
    },
    onSuccess: () => {
      toast.success('Template deleted');
      setSelectedId('');
      void qc.invalidateQueries({ queryKey: ['report-templates', kind] });
    },
    onError: (err) => toastError(err),
  });

  async function handleSave() {
    if (!saveName.trim()) return;
    setSaving(true);
    try {
      await apiFetch('/api/v1/reports/templates', {
        method: 'POST',
        body: {
          kind,
          name: saveName.trim(),
          config: { ...currentConfig, kind },
        },
      });
      toast.success('Template saved');
      setSaveName('');
      setSaveOpen(false);
      void qc.invalidateQueries({ queryKey: ['report-templates', kind] });
    } catch (err) {
      toastError(err);
    } finally {
      setSaving(false);
    }
  }

  function handleApply(id: string) {
    setSelectedId(id);
    const template = data?.data.find((t) => t.id === id);
    if (template) onApply(template);
  }

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

  return (
    <div className="space-y-2">
      <Label className="flex items-center gap-1.5 text-xs uppercase tracking-wide text-muted-foreground">
        <Bookmark className="h-3.5 w-3.5" aria-hidden />
        Saved templates
      </Label>
      <div className="flex items-center gap-2">
        <Select value={selectedId} onValueChange={handleApply} disabled={isLoading}>
          <SelectTrigger className="flex-1">
            <SelectValue
              placeholder={
                isLoading
                  ? 'Loading…'
                  : templates.length === 0
                    ? 'No saved templates yet'
                    : 'Choose a saved template'
              }
            />
          </SelectTrigger>
          <SelectContent>
            {templates.map((t) => (
              <SelectItem key={t.id} value={t.id}>
                {t.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        {selectedId ? (
          <Button
            type="button"
            variant="ghost"
            size="icon"
            onClick={() => deleteMutation.mutate(selectedId)}
            disabled={deleteMutation.isPending}
            aria-label="Delete template"
            title="Delete this saved template"
          >
            <Trash2 className="h-4 w-4 text-destructive" aria-hidden />
          </Button>
        ) : null}
      </div>
      {showSave ? (
        saveOpen ? (
          <div className="flex items-center gap-2">
            <Input
              value={saveName}
              onChange={(e) => setSaveName(e.target.value)}
              placeholder="Template name"
              className="h-8"
            />
            <Button
              type="button"
              size="sm"
              onClick={handleSave}
              disabled={!saveName.trim() || saving}
            >
              {saving ? (
                <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" aria-hidden />
              ) : (
                <Save className="mr-1.5 h-3.5 w-3.5" aria-hidden />
              )}
              Save
            </Button>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => {
                setSaveOpen(false);
                setSaveName('');
              }}
              disabled={saving}
            >
              Cancel
            </Button>
          </div>
        ) : (
          <label className="flex items-center gap-2 text-xs text-muted-foreground cursor-pointer">
            <Checkbox
              checked={false}
              onCheckedChange={(c) => setSaveOpen(Boolean(c))}
              aria-label="Save current config as a template"
            />
            Save the current configuration as a template
          </label>
        )
      ) : null}
    </div>
  );
}
