"use client";

import { useMemo, useState } from "react";
import { KeyRound, Save, Settings as SettingsIcon } from "lucide-react";
import { api, useApi } from "@/lib/client";
import { Button, Card, CardHeader, Field, Input, PageHeader, Select, Tabs, useToast } from "@/components/ui";

interface SettingMeta {
  key: string;
  group: string;
  label: string;
  type: string;
  isSecret: boolean;
}

const GROUP_LABELS: Record<string, string> = {
  general: "ISP information",
  billing: "Billing rules",
  invoice: "Invoice & branding",
  sms: "SMS gateway",
  email: "SMTP / email",
  mikrotik: "MikroTik",
  security: "Security",
  backup: "Backup",
  notification: "Notifications",
};

export default function SettingsPage() {
  const toast = useToast();
  const { data, loading, reload } = useApi<{ settings: Record<string, unknown>; meta: SettingMeta[] }>("/api/settings");
  const [values, setValues] = useState<Record<string, unknown>>({});
  const [busy, setBusy] = useState(false);
  const [groups, setGroups] = useState<string[]>(["general"]);
  const [passwordForm, setPasswordForm] = useState({ currentPassword: "", newPassword: "", confirmPassword: "" });

  const grouped = useMemo(() => {
    const map = new Map<string, SettingMeta[]>();
    for (const meta of data?.meta ?? []) {
      map.set(meta.group, [...(map.get(meta.group) ?? []), meta]);
    }
    return Array.from(map.entries());
  }, [data]);

  const valueOf = (key: string) => (key in values ? values[key] : data?.settings?.[key]);

  const set = (key: string, value: unknown) => setValues((v) => ({ ...v, [key]: value }));

  const save = async () => {
    setBusy(true);
    try {
      const res = await api<{ changed: number }>("/api/settings", { method: "PUT", json: { values } });
      toast.push(`${res.changed} setting(s) saved`, "success");
      setValues({});
      void reload();
    } catch (err) {
      toast.push(err instanceof Error ? err.message : "Save failed", "error");
    } finally {
      setBusy(false);
    }
  };

  const visibleGroups = grouped.filter(([group]) => groups.includes(group));

  return (
    <>
      <PageHeader
        title="System settings"
        subtitle="ISP identity, billing rules, gateways, security and automation"
        icon={<SettingsIcon className="h-5 w-5" />}
        actions={
          <Button size="sm" loading={busy} icon={<Save className="h-4 w-4" />} onClick={() => void save()}>
            Save changes
          </Button>
        }
      />

      <div className="mb-4 flex flex-wrap gap-2">
        {grouped.map(([group]) => (
          <button
            key={group}
            onClick={() => setGroups((g) => (g.includes(group) ? g.filter((x) => x !== group) : [...g, group]))}
            className={`rounded-xl border px-3 py-1.5 text-xs font-medium transition ${
              groups.includes(group) ? "border-brand-400/40 bg-brand-500/15 text-brand-400" : "border-white/8 bg-white/4 text-slate-400 hover:text-slate-200"
            }`}
          >
            {GROUP_LABELS[group] ?? group}
          </button>
        ))}
      </div>

      {loading && !data ? <div className="skeleton h-64 rounded-2xl" /> : null}

      <div className="grid gap-4 lg:grid-cols-2">
        {visibleGroups.map(([group, metas]) => (
          <Card key={group}>
            <CardHeader title={GROUP_LABELS[group] ?? group} subtitle={`${metas.length} setting(s)`} icon={<SettingsIcon className="h-4 w-4" />} />
            <div className="grid gap-4 p-4 sm:grid-cols-2">
              {metas.map((meta) => {
                const value = valueOf(meta.key);
                const isBool = typeof value === "boolean";
                const isNumber = typeof value === "number";
                if (isBool) {
                  return (
                    <label key={meta.key} className="flex items-center gap-2 text-xs text-slate-300">
                      <input type="checkbox" className="h-4 w-4 accent-brand-500" checked={Boolean(value)} onChange={(e) => set(meta.key, e.target.checked)} />
                      {meta.label}
                    </label>
                  );
                }
                if (meta.key === "currency") {
                  return (
                    <Field key={meta.key} label={meta.label}>
                      <Select value={String(value ?? "")} onChange={(e) => set(meta.key, e.target.value)}>
                        {["BDT", "USD", "EUR", "INR", "PKR", "NGN"].map((c) => (
                          <option key={c} value={c}>
                            {c}
                          </option>
                        ))}
                      </Select>
                    </Field>
                  );
                }
                if (meta.key === "smtp_encryption") {
                  return (
                    <Field key={meta.key} label={meta.label}>
                      <Select value={String(value ?? "")} onChange={(e) => set(meta.key, e.target.value)}>
                        {["tls", "ssl", "none"].map((c) => (
                          <option key={c} value={c}>
                            {c}
                          </option>
                        ))}
                      </Select>
                    </Field>
                  );
                }
                return (
                  <Field
                    key={meta.key}
                    label={meta.label}
                    hint={meta.isSecret ? "Stored encrypted — leave blank to keep current value" : undefined}
                    className={meta.type === "textarea" || /address|footer|terms|body/.test(meta.key) ? "sm:col-span-2" : undefined}
                  >
                    <Input
                      type={meta.isSecret ? "password" : isNumber ? "number" : "text"}
                      value={String(value ?? "")}
                      onChange={(e) => set(meta.key, isNumber ? Number(e.target.value) : e.target.value)}
                    />
                  </Field>
                );
              })}
            </div>
          </Card>
        ))}

        <Card>
          <CardHeader title="Change my password" subtitle="Session stays valid, other sessions are unaffected" icon={<KeyRound className="h-4 w-4" />} />
          <div className="grid gap-4 p-4 sm:grid-cols-2">
            <Field label="Current password" className="sm:col-span-2">
              <Input type="password" value={passwordForm.currentPassword} onChange={(e) => setPasswordForm({ ...passwordForm, currentPassword: e.target.value })} />
            </Field>
            <Field label="New password">
              <Input type="password" value={passwordForm.newPassword} onChange={(e) => setPasswordForm({ ...passwordForm, newPassword: e.target.value })} />
            </Field>
            <Field label="Confirm new password">
              <Input type="password" value={passwordForm.confirmPassword} onChange={(e) => setPasswordForm({ ...passwordForm, confirmPassword: e.target.value })} />
            </Field>
            <div className="sm:col-span-2">
              <Button
                onClick={async () => {
                  try {
                    await api("/api/auth/change-password", { method: "POST", json: passwordForm });
                    toast.push("Password updated", "success");
                    setPasswordForm({ currentPassword: "", newPassword: "", confirmPassword: "" });
                  } catch (err) {
                    toast.push(err instanceof Error ? err.message : "Update failed", "error");
                  }
                }}
              >
                Update password
              </Button>
            </div>
          </div>
        </Card>

        <Card>
          <CardHeader title="Cron & automation endpoints" subtitle="Protect with the CRON_SECRET bearer token" />
          <div className="space-y-2 p-4 font-mono text-[11px] text-slate-400">
            {[
              ["*/5 * * * *", "/api/cron/router-status"],
              ["*/5 * * * *", "/api/cron/mikrotik-sync"],
              ["0 1 * * *", "/api/cron/generate-bills"],
              ["30 9 * * *", "/api/cron/due-reminders"],
              ["0 10 * * *", "/api/cron/expiry-reminders"],
              ["0 2 * * *", "/api/cron/auto-disconnect"],
              ["*/30 * * * *", "/api/cron/auto-reconnect"],
              ["0 3 * * *", "/api/cron/backup"],
            ].map(([schedule, path]) => (
              <div key={path} className="flex flex-wrap items-center gap-2 rounded-lg border border-white/8 bg-white/4 px-3 py-2">
                <span className="text-brand-400">{schedule}</span>
                <span className="text-slate-300">{path}</span>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </>
  );
}
