'use client';

import { useState, useEffect, useRef } from 'react';
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
} from '@/components/ui/card';
import { Switch } from '@/components/ui/switch';
import { toast } from 'sonner';
import ProfileSectionSkeleton from './ProfileSectionSkeleton';

interface EventKey {
  key: string;
  displayLabel: string;
  description: string | null;
  sortOrder: number;
}

interface SubscriptionData {
  eventKeys: EventKey[];
  channelTypes: string[];
  matrix: Record<string, Record<string, boolean>>;
}

export function ProfileNotificationMatrix() {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState<SubscriptionData | null>(null);
  const [matrix, setMatrix] = useState<Record<string, Record<string, boolean>>>({});
  // Track per-cell debounce timers keyed by "eventKey::channelType"
  const pendingTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());

  useEffect(() => {
    fetch('/api/me/notification-subscriptions')
      .then((r) => r.json())
      .then((fetched: SubscriptionData) => {
        setData(fetched);
        setMatrix(fetched.matrix);
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  }, []);

  function handleToggle(eventKey: string, channelType: string, newValue: boolean) {
    // Optimistic update
    setMatrix((prev) => ({
      ...prev,
      [eventKey]: {
        ...(prev[eventKey] ?? {}),
        [channelType]: newValue,
      },
    }));

    const cellKey = `${eventKey}::${channelType}`;

    // Clear any existing debounce timer for this cell
    const existing = pendingTimers.current.get(cellKey);
    if (existing) clearTimeout(existing);

    const timer = setTimeout(async () => {
      pendingTimers.current.delete(cellKey);
      try {
        const res = await fetch('/api/me/notification-subscriptions', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            event_key: eventKey,
            channel_type: channelType,
            enabled: newValue,
          }),
        });
        if (!res.ok) {
          throw new Error(`HTTP ${res.status}`);
        }
        toast.success('Preference saved');
      } catch {
        // Revert on error
        setMatrix((prev) => ({
          ...prev,
          [eventKey]: {
            ...(prev[eventKey] ?? {}),
            [channelType]: !newValue,
          },
        }));
        toast.error("Couldn't save preference");
      }
    }, 400);

    pendingTimers.current.set(cellKey, timer);
  }

  if (loading) {
    return <ProfileSectionSkeleton />;
  }

  return (
    <Card>
      <CardHeader className="px-4 pt-4 pb-0">
        <CardTitle className="text-xl font-semibold">Notifications</CardTitle>
        <CardDescription>
          Choose which events trigger a personal notification.
        </CardDescription>
      </CardHeader>
      <CardContent className="px-4 py-4">
        {!data || data.channelTypes.length === 0 ? (
          <p className="text-sm text-muted-foreground">
            Configure a Teams or ntfy channel below to enable personal notifications.
          </p>
        ) : data.channelTypes.length === 1 ? (
          /* Single channel type — simple list, no header row */
          <div className="divide-y">
            {data.eventKeys.map((ek) => {
              const channelType = data.channelTypes[0];
              const checked = matrix[ek.key]?.[channelType] ?? true;
              return (
                <div
                  key={ek.key}
                  className="flex items-center justify-between min-h-[44px] py-3 gap-3"
                >
                  <span className="text-sm flex-1">{ek.displayLabel}</span>
                  <Switch
                    checked={checked}
                    onCheckedChange={(val) => handleToggle(ek.key, channelType, val)}
                    aria-label={ek.displayLabel}
                  />
                </div>
              );
            })}
          </div>
        ) : (
          /* Multiple channel types — grid with header row */
          <div>
            {/* Header row */}
            <div
              className="grid mb-1"
              style={{
                gridTemplateColumns:
                  'minmax(0,1fr) ' + 'repeat(' + data.channelTypes.length + ', 4rem)',
              }}
            >
              <span />
              {data.channelTypes.map((ct) => (
                <span key={ct} className="text-xs text-center capitalize text-muted-foreground">
                  {ct}
                </span>
              ))}
            </div>
            {/* Per event-key rows */}
            {data.eventKeys.map((ek) => (
              <div
                key={ek.key}
                className="grid min-h-[44px] items-center py-3 border-t first:border-t-0"
                style={{
                  gridTemplateColumns:
                    'minmax(0,1fr) ' + 'repeat(' + data.channelTypes.length + ', 4rem)',
                }}
              >
                <span className="text-sm">{ek.displayLabel}</span>
                {data.channelTypes.map((ct) => {
                  const checked = matrix[ek.key]?.[ct] ?? true;
                  return (
                    <div key={ct} className="flex items-center justify-center">
                      <Switch
                        checked={checked}
                        onCheckedChange={(val) => handleToggle(ek.key, ct, val)}
                        aria-label={`${ek.displayLabel} — ${ct}`}
                      />
                    </div>
                  );
                })}
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
