'use client';

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

import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

interface Pref {
  notificationType: string;
  inApp: boolean;
  email: boolean;
}

const KNOWN_TYPES: Array<{ key: string; label: string; description: string }> = [
  {
    key: 'mention',
    label: 'Mentions',
    description: 'When someone @-mentions you in a note.',
  },
  {
    key: 'reminder_overdue',
    label: 'Overdue Reminders',
    description: 'When an interest reminder you own becomes overdue.',
  },
  {
    key: 'interest_stage_changed',
    label: 'Interest Stage Changes',
    description: 'When a pipeline stage changes on an interest assigned to you.',
  },
  {
    key: 'system_alert',
    label: 'System Alerts',
    description: 'Background job failures and maintenance notices.',
  },
];

export function NotificationPreferencesForm() {
  const qc = useQueryClient();
  const { data, isLoading } = useQuery<Pref[]>({
    queryKey: ['notifications', 'preferences'],
    queryFn: () =>
      apiFetch<{ data: Pref[] }>('/api/v1/notifications/preferences').then((r) => r.data),
  });
  // Key-based remount: body keyed on the server payload signature so its
  // useState initializer re-runs when prefs land or change. Replaces the
  // useEffect(setPrefs, [data]) sync the Compiler flagged.
  const signature = data
    ? data.map((p) => `${p.notificationType}:${p.inApp ? 1 : 0}:${p.email ? 1 : 0}`).join('|')
    : 'loading';
  return (
    <NotificationPreferencesFormBody key={signature} data={data} isLoading={isLoading} qc={qc} />
  );
}

function NotificationPreferencesFormBody({
  data,
  isLoading,
  qc,
}: {
  data: Pref[] | undefined;
  isLoading: boolean;
  qc: ReturnType<typeof useQueryClient>;
}) {
  const [prefs, setPrefs] = useState<Map<string, Pref>>(() => {
    const map = new Map<string, Pref>();
    for (const t of KNOWN_TYPES) {
      map.set(t.key, { notificationType: t.key, inApp: true, email: true });
    }
    if (data) {
      for (const p of data) {
        map.set(p.notificationType, p);
      }
    }
    return map;
  });

  const mutation = useMutation({
    mutationFn: async () => {
      const payload = { preferences: Array.from(prefs.values()) };
      return apiFetch('/api/v1/notifications/preferences', {
        method: 'PUT',
        body: payload,
      });
    },
    onSuccess: () => {
      toast.success('Preferences saved');
      qc.invalidateQueries({ queryKey: ['notifications', 'preferences'] });
    },
    onError: (err) => toastError(err),
  });

  function update(type: string, field: 'inApp' | 'email', value: boolean) {
    setPrefs((prev) => {
      const next = new Map(prev);
      const existing = next.get(type) ?? { notificationType: type, inApp: true, email: true };
      next.set(type, { ...existing, [field]: value });
      return next;
    });
  }

  if (isLoading) {
    return <div className="text-sm text-muted-foreground">Loading preferences…</div>;
  }

  return (
    <div className="space-y-4">
      <div className="rounded-lg border divide-y">
        <div className="grid grid-cols-[1fr_auto_auto] gap-4 px-4 py-2 text-xs font-medium uppercase text-muted-foreground">
          <div>Type</div>
          <div className="w-16 text-center">In-app</div>
          <div className="w-16 text-center">Email</div>
        </div>
        {KNOWN_TYPES.map((t) => {
          const pref = prefs.get(t.key) ?? {
            notificationType: t.key,
            inApp: true,
            email: true,
          };
          return (
            <div
              key={t.key}
              className="grid grid-cols-[1fr_auto_auto] gap-4 px-4 py-3 items-center"
            >
              <div>
                <div className="text-sm font-medium">{t.label}</div>
                <div className="text-xs text-muted-foreground">{t.description}</div>
              </div>
              <div className="w-16 flex justify-center">
                <Switch checked={pref.inApp} onCheckedChange={(v) => update(t.key, 'inApp', v)} />
              </div>
              <div className="w-16 flex justify-center">
                <Switch checked={pref.email} onCheckedChange={(v) => update(t.key, 'email', v)} />
              </div>
            </div>
          );
        })}
      </div>
      <div className="flex justify-end">
        <Button onClick={() => mutation.mutate()} disabled={mutation.isPending}>
          {mutation.isPending ? 'Saving…' : 'Save preferences'}
        </Button>
      </div>
    </div>
  );
}
