'use client';

import React, { useEffect, useState, useCallback } from 'react';
import { useTheme } from 'next-themes';
import { adminClient } from '@/lib/api';
import type { AdminSettings } from '@zyphon/api-client';
import { useToast } from '@/components/Toast';
import { useUiPrefs } from '@/components/ThemeProvider';
import { ACCENTS, type AccentId, type DensityId, type FontSizeId, type RadiusId } from '@/lib/ui-prefs';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Segmented } from '@/components/ui/Segmented';
import { Select } from '@/components/ui/Select';
import { Input } from '@/components/ui/Input';
import { cn } from '@/lib/cn';

export default function SettingsPage() {
  const { theme, setTheme } = useTheme();
  const { prefs, setPrefs } = useUiPrefs();
  const { toast } = useToast();
  const [mounted, setMounted] = useState(false);

  const [attempts, setAttempts] = useState(2);
  const [wait, setWait] = useState(1);
  const [trip, setTrip] = useState(3);
  const [pause, setPause] = useState(20);
  const [retention, setRetention] = useState(7);
  const [saving, setSaving] = useState(false);

  // Suppressions state
  const [suppressions, setSuppressions] = useState<{
    sms: string[];
    email: string[];
    whatsapp: string[];
  }>({ sms: [], email: [], whatsapp: [] });
  const [supChannel, setSupChannel] = useState<'sms' | 'email' | 'whatsapp'>('sms');
  const [supInput, setSupInput] = useState('');

  const loadSettings = useCallback(async () => {
    try {
      const s: AdminSettings = await adminClient.getSettings();
      setAttempts(s.retry?.attempts ?? 2);
      setWait(s.retry?.wait ?? 1);
      setTrip(s.circuit_breaker?.trip ?? 3);
      setPause(s.circuit_breaker?.pause ?? 20);
      setRetention(s.retention_days ?? 7);
    } catch {
      /* keep defaults */
    }
    try {
      const supRes = await adminClient.getSuppressions();
      const raw = supRes.suppressions || {};
      setSuppressions({
        sms: Array.isArray(raw.sms) ? raw.sms : [],
        email: Array.isArray(raw.email) ? raw.email : [],
        whatsapp: Array.isArray(raw.whatsapp) ? raw.whatsapp : [],
      });
    } catch {
      /* keep defaults */
    }
  }, []);

  useEffect(() => {
    setMounted(true);
    loadSettings();
  }, [loadSettings]);

  const handleSaveBehavior = async (e: React.FormEvent) => {
    e.preventDefault();
    if (attempts < 1 || wait < 0 || trip < 1 || pause < 1) {
      toast('Please check the values.');
      return;
    }
    setSaving(true);
    try {
      await adminClient.updateSettings({
        retry: { attempts, wait },
        circuit_breaker: { trip, pause },
      });
      toast('Saved');
    } catch (err: unknown) {
      toast(err instanceof Error ? err.message : 'Failed to save settings');
    } finally {
      setSaving(false);
    }
  };

  const handleRetentionChange = async (days: number) => {
    setRetention(days);
    try {
      await adminClient.updateSettings({ retention_days: days });
      toast(`History kept for ${days} days`);
    } catch (err: unknown) {
      toast(err instanceof Error ? err.message : 'Failed to update retention');
    }
  };

  const handleAddSuppression = async (e: React.FormEvent) => {
    e.preventDefault();
    const val = supInput.trim();
    if (!val) return;
    const current = suppressions[supChannel] || [];
    if (current.includes(val)) {
      setSupInput('');
      return;
    }
    const next = {
      ...suppressions,
      [supChannel]: [...current, val],
    };
    setSuppressions(next);
    setSupInput('');
    try {
      await adminClient.updateSuppressions({ suppressions: next });
      toast(`Added ${val} to ${supChannel.toUpperCase()} suppression list`);
    } catch (err: unknown) {
      toast(err instanceof Error ? err.message : 'Failed to update suppressions');
    }
  };

  const handleRemoveSuppression = async (ch: 'sms' | 'email' | 'whatsapp', item: string) => {
    const next = {
      ...suppressions,
      [ch]: (suppressions[ch] || []).filter((x) => x !== item),
    };
    setSuppressions(next);
    try {
      await adminClient.updateSuppressions({ suppressions: next });
      toast('Removed from suppression list');
    } catch (err: unknown) {
      toast(err instanceof Error ? err.message : 'Failed to update suppressions');
    }
  };

  return (
    <div>
      <div className="flex gap-3 items-end justify-between mb-6 flex-wrap">
        <div>
          <h1 className="text-2xl font-bold tracking-tight text-text m-0 mb-1">Settings</h1>
          <div className="text-muted text-sm">
            Console appearance, failover thresholds, DND suppressions, and log retention.
          </div>
        </div>
      </div>

      <Card>
        <h2 className="text-base font-semibold text-text m-0 mb-1">Appearance</h2>
        <div className="text-muted text-[13px] mb-3.5">
          Changes apply instantly and are remembered on this device.
        </div>
        {mounted && (
          <>
            <label className="block mb-4 font-medium text-sm">
              Theme
              <div className="mt-1.5">
                <Segmented
                  className="flex max-w-[420px] w-full"
                  value={(theme as string) || 'system'}
                  onChange={(id) => setTheme(id)}
                  options={[
                    { id: 'light', label: 'Light' },
                    { id: 'dark', label: 'Dark' },
                    { id: 'midnight', label: 'Midnight' },
                    { id: 'system', label: 'System' },
                  ]}
                />
              </div>
            </label>

            <label className="block mb-4 font-medium text-sm">
              Accent colour
              <div className="flex flex-wrap gap-2 mt-2">
                {(Object.keys(ACCENTS) as AccentId[]).map((k) => (
                  <button
                    key={k}
                    type="button"
                    title={k}
                    aria-label={k}
                    onClick={() => setPrefs({ accent: k })}
                    className={cn(
                      'w-[30px] h-[30px] rounded-full border-2 border-transparent cursor-pointer p-0',
                      prefs.accent === k && 'outline outline-2 outline-text outline-offset-2',
                    )}
                    style={{ background: ACCENTS[k][0] }}
                  />
                ))}
              </div>
            </label>

            <div className="grid grid-cols-2 gap-3.5 max-sm:grid-cols-1 mb-4">
              <label className="block font-medium text-sm">
                Density
                <Select
                  className="mt-1.5"
                  value={prefs.density}
                  onChange={(e) => setPrefs({ density: e.target.value as DensityId })}
                >
                  <option value="comfortable">Comfortable</option>
                  <option value="compact">Compact</option>
                </Select>
              </label>
              <label className="block font-medium text-sm">
                Corner radius
                <Select
                  className="mt-1.5"
                  value={prefs.radius}
                  onChange={(e) => setPrefs({ radius: e.target.value as RadiusId })}
                >
                  <option value="default">Default</option>
                  <option value="sharp">Sharp</option>
                  <option value="round">Round</option>
                </Select>
              </label>
              <label className="block font-medium text-sm">
                Text size
                <Select
                  className="mt-1.5"
                  value={prefs.fontSize}
                  onChange={(e) => setPrefs({ fontSize: e.target.value as FontSizeId })}
                >
                  <option value="sm">Small</option>
                  <option value="md">Medium</option>
                  <option value="lg">Large</option>
                </Select>
              </label>
            </div>

            <label className="flex items-center gap-2 text-sm mb-2 cursor-pointer">
              <input
                type="checkbox"
                checked={prefs.highContrast}
                onChange={(e) => setPrefs({ highContrast: e.target.checked })}
              />
              High contrast
            </label>
            <label className="flex items-center gap-2 text-sm cursor-pointer">
              <input
                type="checkbox"
                checked={prefs.reduceMotion}
                onChange={(e) => setPrefs({ reduceMotion: e.target.checked })}
              />
              Reduce motion
            </label>
          </>
        )}
      </Card>

      <Card>
        <h2 className="text-base font-semibold text-text m-0 mb-1">When sending fails</h2>
        <div className="text-muted text-[13px] mb-3.5">
          Zyphon retries, then switches to your backup provider automatically.
        </div>
        <form onSubmit={handleSaveBehavior} className="space-y-3.5">
          <div className="grid grid-cols-2 gap-3.5 max-sm:grid-cols-1">
            <label className="block text-sm font-medium">
              Retry each provider
              <Input
                type="number"
                min={1}
                max={5}
                className="mt-1"
                value={attempts}
                onChange={(e) => setAttempts(+e.target.value)}
              />
              <small className="text-muted text-xs block mt-1">times before moving to the backup</small>
            </label>
            <label className="block text-sm font-medium">
              Wait between retries
              <Input
                type="number"
                min={0}
                className="mt-1"
                value={wait}
                onChange={(e) => setWait(+e.target.value)}
              />
              <small className="text-muted text-xs block mt-1">seconds</small>
            </label>
            <label className="block text-sm font-medium">
              Pause a provider after
              <Input
                type="number"
                min={1}
                className="mt-1"
                value={trip}
                onChange={(e) => setTrip(+e.target.value)}
              />
              <small className="text-muted text-xs block mt-1">failures in a row</small>
            </label>
            <label className="block text-sm font-medium">
              Pause it for
              <Input
                type="number"
                min={1}
                className="mt-1"
                value={pause}
                onChange={(e) => setPause(+e.target.value)}
              />
              <small className="text-muted text-xs block mt-1">seconds</small>
            </label>
          </div>
          <Button type="submit" variant="primary" disabled={saving}>
            {saving ? 'Saving…' : 'Save'}
          </Button>
        </form>
      </Card>

      <Card>
        <h2 className="text-base font-semibold text-text m-0 mb-1">DND & Suppression lists</h2>
        <div className="text-muted text-[13px] mb-3.5">
          Blocked recipients are rejected before reaching any provider.
        </div>
        <form onSubmit={handleAddSuppression} className="flex gap-2 mb-3 flex-wrap">
          <Select
            className="w-auto"
            value={supChannel}
            onChange={(e) => setSupChannel(e.target.value as any)}
          >
            <option value="sms">SMS</option>
            <option value="email">Email</option>
            <option value="whatsapp">WhatsApp</option>
          </Select>
          <Input
            className="flex-1 min-w-[200px]"
            placeholder={supChannel === 'email' ? 'blocked@domain.com' : '+919876543210'}
            value={supInput}
            onChange={(e) => setSupInput(e.target.value)}
          />
          <Button type="submit">Block recipient</Button>
        </form>
        <div className="flex flex-wrap gap-2">
          {(['sms', 'email', 'whatsapp'] as const).flatMap((ch) =>
            (suppressions[ch] || []).map((item) => (
              <span
                key={`${ch}:${item}`}
                className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-mono border border-line bg-surface-2"
              >
                <span className="uppercase text-muted">{ch}:</span>
                <b>{item}</b>
                <button
                  type="button"
                  onClick={() => handleRemoveSuppression(ch, item)}
                  className="text-muted hover:text-danger border-0 bg-transparent cursor-pointer px-1"
                >
                  ✕
                </button>
              </span>
            )),
          )}
          {suppressions.sms.length === 0 &&
            suppressions.email.length === 0 &&
            suppressions.whatsapp.length === 0 && (
              <span className="text-xs text-muted">No recipients suppressed.</span>
            )}
        </div>
      </Card>

      <Card className="mb-0">
        <h2 className="text-base font-semibold text-text m-0 mb-1">Message history</h2>
        <div className="text-muted text-[13px] mb-3">Older messages are deleted automatically.</div>
        <Select
          className="w-auto"
          value={retention}
          onChange={(e) => handleRetentionChange(+e.target.value)}
        >
          {[3, 7, 14, 30].map((d) => (
            <option key={d} value={d}>
              Keep {d} days
            </option>
          ))}
        </Select>
      </Card>
    </div>
  );
}
