'use client';

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

import { PageHeader } from '@/components/shared/page-header';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

type Mode = 'auto' | 'suggest' | 'off';

const TRIGGERS: Array<{
  key: string;
  label: string;
  description: string;
  defaultMode: Mode;
}> = [
  {
    key: 'eoi_sent',
    label: 'EOI sent',
    description: 'Rep generates an EOI for signing  -  moves the deal to "EOI" stage.',
    defaultMode: 'auto',
  },
  {
    key: 'eoi_signed',
    label: 'EOI signed (all parties)',
    description:
      'All signatories complete the EOI  -  moves the deal to "Reservation" stage. Conventional CRM behaviour.',
    defaultMode: 'auto',
  },
  {
    key: 'reservation_signed',
    label: 'Reservation agreement signed',
    description:
      'Reservation paperwork signed by all parties  -  keeps the deal at "Reservation" with sub-status signed.',
    defaultMode: 'auto',
  },
  {
    key: 'deposit_received',
    label: 'Deposit received in full',
    description:
      'Deposit total reaches the expected amount  -  moves the deal to "Deposit Paid" stage.',
    defaultMode: 'auto',
  },
  {
    key: 'contract_signed',
    label: 'Sales contract signed',
    description: 'Final contract signed by all parties  -  moves the deal to "Contract" stage.',
    defaultMode: 'auto',
  },
];

const PRESETS = {
  aggressive: 'auto',
  conservative: 'suggest',
} as const;
type PresetName = keyof typeof PRESETS;

export default function PipelineRulesPage() {
  const queryClient = useQueryClient();
  const [rules, setRules] = useState<Record<string, Mode>>(() =>
    Object.fromEntries(TRIGGERS.map((t) => [t.key, t.defaultMode])),
  );

  const { data, isLoading } = useQuery<{
    data: { values: Record<string, { value?: Record<string, Mode> | null }> };
  }>({
    queryKey: ['admin', 'settings', 'pipeline.auto_advance'],
    queryFn: () =>
      apiFetch<{
        data: { values: Record<string, { value?: Record<string, Mode> | null }> };
      }>('/api/v1/admin/settings/resolved?sections=pipeline.auto_advance'),
  });

  // Hydrate the local form once the server-side state arrives. We treat
  // missing keys as the registered default - the page's persisted JSON
  // doesn't have to enumerate every trigger, just the overrides.
  useEffect(() => {
    const persisted = data?.data?.values?.stage_advance_rules?.value;
    if (!persisted || typeof persisted !== 'object') return;
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setRules((prev) => {
      const next = { ...prev };
      for (const t of TRIGGERS) {
        const v = persisted[t.key];
        if (v === 'auto' || v === 'suggest' || v === 'off') next[t.key] = v;
      }
      return next;
    });
  }, [data]);

  const saveMutation = useMutation({
    mutationFn: () =>
      apiFetch('/api/v1/admin/settings/stage_advance_rules', {
        method: 'PUT',
        body: { value: rules },
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin', 'settings'] });
      toast.success('Pipeline rules saved.');
    },
    onError: (err) => toastError(err),
  });

  const applyPreset = (preset: PresetName) => {
    const target = PRESETS[preset];
    setRules(Object.fromEntries(TRIGGERS.map((t) => [t.key, target])));
  };

  const setMode = (key: string, mode: Mode) => {
    setRules((prev) => ({ ...prev, [key]: mode }));
  };

  const allMatch = (mode: Mode) => TRIGGERS.every((t) => rules[t.key] === mode);
  const currentPreset: PresetName | 'custom' = allMatch('auto')
    ? 'aggressive'
    : allMatch('suggest')
      ? 'conservative'
      : 'custom';

  return (
    <div className="space-y-6">
      <PageHeader
        title="Pipeline auto-advance rules"
        description="Control which lifecycle events (signing, payments) automatically advance the deal stage on the kanban. Choose a preset or fine-tune per trigger."
      />

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Preset</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="grid gap-2 sm:grid-cols-3">
            <PresetButton
              name="aggressive"
              label="Aggressive (default)"
              description="Every trigger auto-advances the stage. Matches conventional CRM behaviour and saves rep clicks."
              active={currentPreset === 'aggressive'}
              onClick={() => applyPreset('aggressive')}
            />
            <PresetButton
              name="conservative"
              label="Conservative"
              description="Every trigger sends a notification suggesting the move. Reps click Approve to advance."
              active={currentPreset === 'conservative'}
              onClick={() => applyPreset('conservative')}
            />
            <div
              className={`rounded-lg border p-3 ${
                currentPreset === 'custom'
                  ? 'border-primary bg-primary/5'
                  : 'border-muted bg-muted/20'
              }`}
            >
              <p className="text-sm font-semibold">Custom</p>
              <p className="text-xs text-muted-foreground">
                Mix and match - the per-trigger toggles below override the preset.
              </p>
            </div>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Per-trigger settings</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          {isLoading ? (
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <Loader2 className="size-3.5 animate-spin" aria-hidden /> Loading…
            </div>
          ) : (
            TRIGGERS.map((t) => (
              <div
                key={t.key}
                className="flex flex-col gap-2 rounded-md border p-3 sm:flex-row sm:items-center sm:justify-between"
              >
                <div className="flex-1">
                  <p className="text-sm font-medium">{t.label}</p>
                  <p className="text-xs text-muted-foreground">{t.description}</p>
                </div>
                <div className="flex items-center gap-2">
                  <Label htmlFor={`mode-${t.key}`} className="sr-only">
                    Mode
                  </Label>
                  <Select
                    value={rules[t.key] ?? t.defaultMode}
                    onValueChange={(v) => setMode(t.key, v as Mode)}
                  >
                    <SelectTrigger id={`mode-${t.key}`} className="w-40">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="auto">Auto-advance</SelectItem>
                      <SelectItem value="suggest">Suggest only</SelectItem>
                      <SelectItem value="off">Off</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
            ))
          )}
        </CardContent>
      </Card>

      <div className="flex justify-end">
        <Button
          onClick={() => saveMutation.mutate()}
          disabled={saveMutation.isPending}
          className="gap-1.5 [&_svg]:size-3.5"
        >
          {saveMutation.isPending ? <Loader2 className="animate-spin" aria-hidden /> : <Save />}
          Save rules
        </Button>
      </div>
    </div>
  );
}

function PresetButton({
  name,
  label,
  description,
  active,
  onClick,
}: {
  name: PresetName;
  label: string;
  description: string;
  active: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={`rounded-lg border p-3 text-left transition-colors ${
        active
          ? 'border-primary bg-primary/5 ring-2 ring-primary/40'
          : 'border-muted hover:border-foreground/30 hover:bg-muted/30'
      }`}
      aria-pressed={active}
    >
      <p className="text-sm font-semibold">{label}</p>
      <p className="text-xs text-muted-foreground">{description}</p>
      <p className="mt-1 text-xs uppercase tracking-wide text-muted-foreground">
        {name === 'aggressive' ? 'auto for all triggers' : 'suggest for all triggers'}
      </p>
    </button>
  );
}
