import { useState, useEffect, useRef } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Settings,
  Mail,
  Webhook,
  Bell,
  User,
  Plus,
  Trash2,
  TestTube,
  Save,
  Eye,
  EyeOff,
  CheckCircle,
  XCircle,
  AlertCircle,
  Loader2,
  Edit2,
  X,
  Link2,
  KeyRound,
  Copy,
  Building2,
  Server,
  Database,
  HardDrive,
  Clock,
  PackageOpen,
  Download,
  Upload,
  ShieldCheck,
} from "lucide-react";
import { useAuth } from "../context/AuthContext";
import client from "../api/client";
import {
  getSsoConfig,
  updateSsoConfig,
  type SsoConfig,
  type SsoConfigUpdate,
} from "../api/sso";
import {
  getEmailConfig,
  updateEmailConfig,
  sendTestEmail,
  getWebhooks,
  createWebhook,
  updateWebhook,
  deleteWebhook,
  testWebhook,
  getMe,
  updateMyPreferences,
  getJiraConfig,
  updateJiraConfig,
  testJiraConnection,
  testTempoConnection,
  type EmailConfigUpdate,
  type WebhookCreate,
  type WebhookOut,
  type NotificationPreferences,
  type JiraConfigUpdate,
} from "../api/settings";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function Section({
  title,
  icon: Icon,
  children,
}: {
  title: string;
  icon: React.FC<{ className?: string }>;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
      <h2 className="mb-6 flex items-center gap-2 text-lg font-semibold text-white">
        <Icon className="h-5 w-5 text-cyan-400" />
        {title}
      </h2>
      {children}
    </div>
  );
}

function ToggleRow({
  label,
  description,
  checked,
  onChange,
}: {
  label: string;
  description?: string;
  checked: boolean;
  onChange: (v: boolean) => void;
}) {
  return (
    <div className="flex items-center justify-between py-3 border-b border-gray-800 last:border-0">
      <div>
        <p className="text-sm font-medium text-gray-200">{label}</p>
        {description && <p className="text-xs text-gray-500">{description}</p>}
      </div>
      <button
        type="button"
        onClick={() => onChange(!checked)}
        className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
          checked ? "bg-cyan-500" : "bg-gray-700"
        }`}
      >
        <span
          className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
            checked ? "translate-x-6" : "translate-x-1"
          }`}
        />
      </button>
    </div>
  );
}

function Toast({
  message,
  type,
  onClose,
}: {
  message: string;
  type: "success" | "error";
  onClose: () => void;
}) {
  return (
    <div
      className={`fixed bottom-6 right-6 z-50 flex items-center gap-3 rounded-lg px-4 py-3 shadow-lg text-sm font-medium ${
        type === "success"
          ? "bg-emerald-900/90 text-emerald-300 border border-emerald-700"
          : "bg-red-900/90 text-red-300 border border-red-700"
      }`}
    >
      {type === "success" ? (
        <CheckCircle className="h-4 w-4 shrink-0" />
      ) : (
        <XCircle className="h-4 w-4 shrink-0" />
      )}
      {message}
      <button onClick={onClose} className="ml-2 opacity-60 hover:opacity-100">
        <X className="h-4 w-4" />
      </button>
    </div>
  );
}

// ---------------------------------------------------------------------------
// SMTP Email Section (admin only)
// ---------------------------------------------------------------------------

const AVAILABLE_EVENTS = [
  "test.validated",
  "test.rejected",
  "campaign.completed",
  "campaign.started",
  "mitre.synced",
  "webhook.test",
];

function EmailSection() {
  const qc = useQueryClient();
  const [showPw, setShowPw] = useState(false);
  const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);
  const [testEmail, setTestEmail] = useState("");

  const { data: cfg, isLoading } = useQuery({
    queryKey: ["email-config"],
    queryFn: getEmailConfig,
  });

  const [form, setForm] = useState<EmailConfigUpdate & { password?: string }>({});
  const effective = { ...cfg, ...form };

  const saveMutation = useMutation({
    mutationFn: updateEmailConfig,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["email-config"] });
      setForm({});
      setToast({ msg: "Email configuration saved", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to save email configuration", type: "error" }),
  });

  const testMutation = useMutation({
    mutationFn: () => sendTestEmail(testEmail),
    onSuccess: () => setToast({ msg: `Test email sent to ${testEmail}`, type: "success" }),
    onError: () =>
      setToast({ msg: "Failed to send test email. Check SMTP settings and logs.", type: "error" }),
  });

  if (isLoading) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
      </div>
    );
  }

  const field = (
    key: keyof EmailConfigUpdate,
    label: string,
    type = "text",
    placeholder = ""
  ) => (
    <div>
      <label className="mb-1 block text-xs font-medium text-gray-400">{label}</label>
      <input
        type={type}
        value={String(form[key] ?? cfg?.[key as keyof typeof cfg] ?? "")}
        onChange={(e) =>
          setForm((prev) => ({ ...prev, [key]: e.target.value }))
        }
        placeholder={placeholder}
        className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
      />
    </div>
  );

  return (
    <>
      {toast && (
        <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />
      )}
      <div className="space-y-4">
        {/* Enable toggle */}
        <ToggleRow
          label="Enable email notifications"
          description="When disabled, no emails are sent regardless of other settings"
          checked={Boolean(form.enabled !== undefined ? form.enabled : cfg?.enabled)}
          onChange={(v) => setForm((prev) => ({ ...prev, enabled: v }))}
        />

        <div className="grid grid-cols-2 gap-4 pt-2">
          {field("host", "SMTP Host", "text", "smtp.gmail.com")}
          <div>
            <label className="mb-1 block text-xs font-medium text-gray-400">SMTP Port</label>
            <input
              type="number"
              value={String(form.port ?? cfg?.port ?? 587)}
              onChange={(e) =>
                setForm((prev) => ({ ...prev, port: parseInt(e.target.value) || 587 }))
              }
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 focus:border-cyan-500 focus:outline-none"
            />
          </div>
          {field("username", "Username / Email", "text", "you@company.com")}
          <div>
            <label className="mb-1 block text-xs font-medium text-gray-400">Password</label>
            <div className="relative">
              <input
                type={showPw ? "text" : "password"}
                value={String(form.password ?? "")}
                onChange={(e) => setForm((prev) => ({ ...prev, password: e.target.value }))}
                placeholder="Leave blank to keep current"
                className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 pr-10 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
              />
              <button
                type="button"
                onClick={() => setShowPw(!showPw)}
                className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-300"
              >
                {showPw ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
              </button>
            </div>
          </div>
          {field("from_email", "From Address", "email", "aegis@company.com")}
        </div>

        <ToggleRow
          label="Use TLS (STARTTLS)"
          checked={Boolean(form.use_tls !== undefined ? form.use_tls : cfg?.use_tls)}
          onChange={(v) => setForm((prev) => ({ ...prev, use_tls: v }))}
        />

        <div className="flex items-center justify-between pt-2">
          <button
            onClick={() => {
              if (Object.keys(form).length > 0) saveMutation.mutate(form);
            }}
            disabled={saveMutation.isPending || Object.keys(form).length === 0}
            className="flex items-center gap-2 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
          >
            {saveMutation.isPending ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Save className="h-4 w-4" />
            )}
            Save Configuration
          </button>
        </div>

        {/* Test email */}
        <div className="mt-4 rounded-lg border border-gray-700 bg-gray-800/50 p-4">
          <p className="mb-3 text-sm font-medium text-gray-300">Send Test Email</p>
          <div className="flex gap-2">
            <input
              type="email"
              value={testEmail}
              onChange={(e) => setTestEmail(e.target.value)}
              placeholder="recipient@example.com"
              className="flex-1 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
            />
            <button
              onClick={() => testEmail && testMutation.mutate()}
              disabled={testMutation.isPending || !testEmail}
              className="flex items-center gap-2 rounded-lg border border-cyan-700 px-4 py-2 text-sm font-medium text-cyan-400 hover:bg-cyan-900/30 disabled:opacity-50 transition-colors"
            >
              {testMutation.isPending ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <TestTube className="h-4 w-4" />
              )}
              Send Test
            </button>
          </div>
        </div>
      </div>
    </>
  );
}

// ---------------------------------------------------------------------------
// Webhooks Section (admin + leads)
// ---------------------------------------------------------------------------

function WebhookForm({
  initial,
  onSave,
  onCancel,
  isSaving,
}: {
  initial?: Partial<WebhookCreate>;
  onSave: (data: WebhookCreate) => void;
  onCancel: () => void;
  isSaving: boolean;
}) {
  const [form, setForm] = useState<WebhookCreate>({
    name: initial?.name ?? "",
    url: initial?.url ?? "",
    secret: initial?.secret ?? "",
    events: initial?.events ?? [],
    is_active: initial?.is_active ?? true,
  });

  const toggleEvent = (ev: string) => {
    setForm((prev) => ({
      ...prev,
      events: prev.events.includes(ev)
        ? prev.events.filter((e) => e !== ev)
        : [...prev.events, ev],
    }));
  };

  return (
    <div className="rounded-lg border border-cyan-800/50 bg-gray-800/50 p-4 space-y-4">
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="mb-1 block text-xs font-medium text-gray-400">Name</label>
          <input
            value={form.name}
            onChange={(e) => setForm((p) => ({ ...p, name: e.target.value }))}
            placeholder="My Webhook"
            className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
          />
        </div>
        <div>
          <label className="mb-1 block text-xs font-medium text-gray-400">URL</label>
          <input
            value={form.url}
            onChange={(e) => setForm((p) => ({ ...p, url: e.target.value }))}
            placeholder="https://hooks.example.com/..."
            className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
          />
        </div>
        <div className="col-span-2">
          <label className="mb-1 block text-xs font-medium text-gray-400">
            Secret (optional — used for HMAC-SHA256 signature)
          </label>
          <input
            value={form.secret ?? ""}
            onChange={(e) => setForm((p) => ({ ...p, secret: e.target.value }))}
            placeholder="supersecretkey"
            className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
          />
        </div>
      </div>
      <div>
        <label className="mb-2 block text-xs font-medium text-gray-400">Events</label>
        <div className="flex flex-wrap gap-2">
          {AVAILABLE_EVENTS.map((ev) => (
            <button
              key={ev}
              type="button"
              onClick={() => toggleEvent(ev)}
              className={`rounded-full px-3 py-1 text-xs font-medium transition-colors ${
                form.events.includes(ev)
                  ? "bg-cyan-600 text-white"
                  : "bg-gray-700 text-gray-400 hover:bg-gray-600"
              }`}
            >
              {ev}
            </button>
          ))}
        </div>
      </div>
      <ToggleRow
        label="Active"
        checked={form.is_active ?? true}
        onChange={(v) => setForm((p) => ({ ...p, is_active: v }))}
      />
      <div className="flex gap-2 pt-1">
        <button
          onClick={() => onSave(form)}
          disabled={isSaving || !form.name || !form.url || form.events.length === 0}
          className="flex items-center gap-2 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
        >
          {isSaving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
          Save
        </button>
        <button
          onClick={onCancel}
          className="rounded-lg border border-gray-700 px-4 py-2 text-sm font-medium text-gray-400 hover:text-gray-200 hover:border-gray-500 transition-colors"
        >
          Cancel
        </button>
      </div>
    </div>
  );
}

function WebhooksSection() {
  const qc = useQueryClient();
  const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);
  const [creating, setCreating] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);

  const { data: webhooks = [], isLoading } = useQuery({
    queryKey: ["webhooks"],
    queryFn: getWebhooks,
  });

  const createMut = useMutation({
    mutationFn: createWebhook,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["webhooks"] });
      setCreating(false);
      setToast({ msg: "Webhook created", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to create webhook", type: "error" }),
  });

  const updateMut = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<WebhookCreate> }) =>
      updateWebhook(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["webhooks"] });
      setEditingId(null);
      setToast({ msg: "Webhook updated", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to update webhook", type: "error" }),
  });

  const deleteMut = useMutation({
    mutationFn: deleteWebhook,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["webhooks"] });
      setToast({ msg: "Webhook deleted", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to delete webhook", type: "error" }),
  });

  const testMut = useMutation({
    mutationFn: testWebhook,
    onSuccess: () => setToast({ msg: "Test ping dispatched", type: "success" }),
    onError: () => setToast({ msg: "Ping failed", type: "error" }),
  });

  if (isLoading) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
      </div>
    );
  }

  return (
    <>
      {toast && (
        <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />
      )}
      <div className="space-y-3">
        {webhooks.length === 0 && !creating && (
          <p className="text-center py-6 text-sm text-gray-500">No webhooks configured yet.</p>
        )}

        {webhooks.map((wh) =>
          editingId === wh.id ? (
            <WebhookForm
              key={wh.id}
              initial={{
                name: wh.name,
                url: wh.url,
                events: wh.events,
                is_active: wh.is_active,
              }}
              onSave={(data) => updateMut.mutate({ id: wh.id, data })}
              onCancel={() => setEditingId(null)}
              isSaving={updateMut.isPending}
            />
          ) : (
            <WebhookRow
              key={wh.id}
              wh={wh}
              onEdit={() => setEditingId(wh.id)}
              onDelete={() => deleteMut.mutate(wh.id)}
              onTest={() => testMut.mutate(wh.id)}
              isDeleting={deleteMut.isPending}
              isTesting={testMut.isPending}
            />
          )
        )}

        {creating && (
          <WebhookForm
            onSave={(data) => createMut.mutate(data)}
            onCancel={() => setCreating(false)}
            isSaving={createMut.isPending}
          />
        )}

        {!creating && (
          <button
            onClick={() => setCreating(true)}
            className="flex items-center gap-2 rounded-lg border border-dashed border-gray-700 px-4 py-2.5 text-sm font-medium text-gray-500 hover:border-cyan-700 hover:text-cyan-400 transition-colors w-full justify-center"
          >
            <Plus className="h-4 w-4" />
            Add Webhook
          </button>
        )}
      </div>
    </>
  );
}

function WebhookRow({
  wh,
  onEdit,
  onDelete,
  onTest,
  isDeleting,
  isTesting,
}: {
  wh: WebhookOut;
  onEdit: () => void;
  onDelete: () => void;
  onTest: () => void;
  isDeleting: boolean;
  isTesting: boolean;
}) {
  return (
    <div className="rounded-lg border border-gray-800 bg-gray-800/30 p-4">
      <div className="flex items-start justify-between gap-4">
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2">
            <span className="font-medium text-sm text-gray-200">{wh.name}</span>
            <span
              className={`text-[10px] font-semibold uppercase rounded-full px-2 py-0.5 ${
                wh.is_active
                  ? "bg-emerald-900/50 text-emerald-400"
                  : "bg-gray-700 text-gray-500"
              }`}
            >
              {wh.is_active ? "active" : "inactive"}
            </span>
            {wh.failure_count > 0 && (
              <span className="text-[10px] font-semibold uppercase rounded-full px-2 py-0.5 bg-red-900/50 text-red-400 flex items-center gap-1">
                <AlertCircle className="h-3 w-3" />
                {wh.failure_count} failures
              </span>
            )}
          </div>
          <p className="mt-0.5 text-xs text-gray-500 truncate">{wh.url}</p>
          <div className="mt-1.5 flex flex-wrap gap-1">
            {wh.events.map((ev) => (
              <span
                key={ev}
                className="text-[10px] rounded-full bg-gray-700 px-2 py-0.5 text-gray-400"
              >
                {ev}
              </span>
            ))}
          </div>
        </div>
        <div className="flex items-center gap-1.5 shrink-0">
          <button
            onClick={onTest}
            disabled={isTesting}
            title="Send test ping"
            className="p-1.5 rounded-lg text-gray-500 hover:text-cyan-400 hover:bg-cyan-900/20 transition-colors disabled:opacity-40"
          >
            {isTesting ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <TestTube className="h-4 w-4" />
            )}
          </button>
          <button
            onClick={onEdit}
            title="Edit"
            className="p-1.5 rounded-lg text-gray-500 hover:text-gray-200 hover:bg-gray-700 transition-colors"
          >
            <Edit2 className="h-4 w-4" />
          </button>
          <button
            onClick={onDelete}
            disabled={isDeleting}
            title="Delete"
            className="p-1.5 rounded-lg text-gray-500 hover:text-red-400 hover:bg-red-900/20 transition-colors disabled:opacity-40"
          >
            <Trash2 className="h-4 w-4" />
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Notification Preferences Section (all users)
// ---------------------------------------------------------------------------

const PREF_DEFS: {
  key: keyof NotificationPreferences;
  label: string;
  description?: string;
  roles: string[]; // roles that see this pref
}[] = [
  {
    key: "email_on_test_validated",
    label: "Email on test validated",
    description: "Receive an email when a test you're involved with gets validated",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech", "viewer"],
  },
  {
    key: "email_on_test_rejected",
    label: "Email on test rejected",
    description: "Receive an email when a test you submitted gets rejected",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech"],
  },
  {
    key: "email_on_campaign_completed",
    label: "Email on campaign completed",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech"],
  },
  {
    key: "email_on_new_mitre_techniques",
    label: "Email on new MITRE techniques",
    description: "Get notified when the MITRE ATT&CK sync adds new techniques",
    roles: ["admin", "red_lead", "blue_lead"],
  },
  {
    key: "email_on_stale_coverage",
    label: "Email on stale coverage alert",
    description: "Notified when techniques haven't been tested in a long time",
    roles: ["admin", "red_lead", "blue_lead"],
  },
  {
    key: "email_on_assigned_to_campaign",
    label: "Email when assigned to a campaign",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech"],
  },
  {
    key: "email_on_test_state_change",
    label: "Email on test state change",
    description: "Notified when tests move through the validation workflow",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech"],
  },
  {
    key: "email_on_all_team_validations",
    label: "Email on all team validations",
    description: "Lead-level: receive email for every validation in your team",
    roles: ["admin", "red_lead", "blue_lead"],
  },
  {
    key: "email_on_webhook_failures",
    label: "Email on webhook delivery failures",
    roles: ["admin", "red_lead", "blue_lead"],
  },
  {
    key: "email_on_new_users",
    label: "Email on new user registration",
    roles: ["admin"],
  },
  {
    key: "email_on_system_errors",
    label: "Email on system errors",
    description: "Critical errors in background jobs and integrations",
    roles: ["admin"],
  },
  {
    key: "in_app_all",
    label: "In-app notifications",
    description: "Show notification bell alerts inside Aegis",
    roles: ["admin", "red_lead", "blue_lead", "red_tech", "blue_tech", "viewer"],
  },
];

const DEFAULT_PREFS: NotificationPreferences = {
  email_on_test_validated: true,
  email_on_test_rejected: true,
  email_on_campaign_completed: true,
  email_on_new_mitre_techniques: false,
  email_on_stale_coverage: false,
  email_on_assigned_to_campaign: true,
  email_on_test_state_change: true,
  email_on_all_team_validations: false,
  email_on_webhook_failures: true,
  email_on_new_users: false,
  email_on_system_errors: true,
  in_app_all: true,
};

function NotificationSection() {
  const qc = useQueryClient();
  const { user } = useAuth();
  const role = user?.role ?? "viewer";

  const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);

  const { data: me, isLoading } = useQuery({
    queryKey: ["me-prefs"],
    queryFn: getMe,
  });

  const [localPrefs, setLocalPrefs] = useState<Partial<NotificationPreferences>>({});
  const [jiraAccountId, setJiraAccountId] = useState<string>("");
  const [jiraIdDirty, setJiraIdDirty] = useState(false);

  const effectivePrefs: NotificationPreferences = {
    ...DEFAULT_PREFS,
    ...(me?.notification_preferences ?? {}),
    ...localPrefs,
  };

  const saveMut = useMutation({
    mutationFn: updateMyPreferences,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["me-prefs"] });
      setLocalPrefs({});
      setJiraIdDirty(false);
      setToast({ msg: "Preferences saved", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to save preferences", type: "error" }),
  });

  const handleSave = () => {
    const payload: Parameters<typeof updateMyPreferences>[0] = {};
    if (Object.keys(localPrefs).length > 0) {
      payload.notification_preferences = {
        ...(me?.notification_preferences ?? {}),
        ...localPrefs,
      };
    }
    if (jiraIdDirty) {
      payload.jira_account_id = jiraAccountId || null;
    }
    if (Object.keys(payload).length > 0) {
      saveMut.mutate(payload);
    }
  };

  const isDirty = Object.keys(localPrefs).length > 0 || jiraIdDirty;

  if (isLoading) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
      </div>
    );
  }

  const visiblePrefs = PREF_DEFS.filter((d) => d.roles.includes(role));

  return (
    <>
      {toast && (
        <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />
      )}
      <div className="space-y-1">
        {visiblePrefs.map((def) => (
          <ToggleRow
            key={def.key}
            label={def.label}
            description={def.description}
            checked={Boolean(effectivePrefs[def.key])}
            onChange={(v) => setLocalPrefs((prev) => ({ ...prev, [def.key]: v }))}
          />
        ))}
      </div>

      <div className="mt-4 flex justify-end">
        <button
          onClick={handleSave}
          disabled={saveMut.isPending || !isDirty}
          className="flex items-center gap-2 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
        >
          {saveMut.isPending ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : (
            <Save className="h-4 w-4" />
          )}
          Save Preferences
        </button>
      </div>
    </>
  );
}

// ---------------------------------------------------------------------------
// Profile / Jira Section (all users)
// ---------------------------------------------------------------------------

function ProfileSection() {
  const { data: me, isLoading } = useQuery({
    queryKey: ["me-prefs"],
    queryFn: getMe,
  });

  if (isLoading) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-2 gap-4 text-sm">
        <div>
          <p className="text-xs text-gray-500 mb-1">Username</p>
          <p className="text-gray-300 font-medium">{me?.username}</p>
        </div>
        <div>
          <p className="text-xs text-gray-500 mb-1">Role</p>
          <p className="text-gray-300 font-medium capitalize">{me?.role?.replace("_", " ")}</p>
        </div>
        <div>
          <p className="text-xs text-gray-500 mb-1">Email</p>
          <p className="text-gray-300">{me?.email ?? "—"}</p>
        </div>
        <div>
          <p className="text-xs text-gray-500 mb-1">Last Login</p>
          <p className="text-gray-300">
            {me?.last_login
              ? new Date(me.last_login).toLocaleString("en-US", {
                  timeZone: "UTC",
                  year: "numeric",
                  month: "short",
                  day: "numeric",
                  hour: "2-digit",
                  minute: "2-digit",
                }) + " UTC"
              : "—"}
          </p>
        </div>
      </div>

      <div className="border-t border-gray-800 pt-4">
        <p className="text-sm font-semibold text-gray-300 mb-1">Jira / Tempo</p>
        <p className="text-xs text-gray-500 mb-3">
          Your Atlassian account ID is detected automatically on login using the admin Jira account. No personal tokens required.
        </p>
        <div className="flex items-center gap-3">
          <span className="text-xs text-gray-500">Account ID:</span>
          {me?.jira_account_id ? (
            <code className="rounded bg-gray-800 border border-gray-700 px-2 py-1 text-xs text-cyan-300 font-mono">
              {me.jira_account_id}
            </code>
          ) : (
            <span className="inline-flex items-center gap-1 rounded-full bg-gray-800 border border-gray-700 px-2 py-0.5 text-[11px] text-gray-500">
              Not detected yet — log out and back in after admin configures Jira
            </span>
          )}
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Jira Admin Config Section (admin only)
// ---------------------------------------------------------------------------

function JiraConfigSection() {
  const qc = useQueryClient();
  const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);
  const [showAdminToken, setShowAdminToken] = useState(false);
  const [showTempoToken, setShowTempoToken] = useState(false);
  const [jiraTestResult, setJiraTestResult] = useState<{ connectedAs: string; url: string } | null>(null);
  const [jiraTestError, setJiraTestError] = useState<string | null>(null);
  const [tempoTestResult, setTempoTestResult] = useState<string | null>(null);
  const [tempoTestError, setTempoTestError] = useState<string | null>(null);

  const { data: cfg, isLoading } = useQuery({
    queryKey: ["jira-config"],
    queryFn: getJiraConfig,
  });

  const [form, setForm] = useState<JiraConfigUpdate>({});

  const saveMut = useMutation({
    mutationFn: updateJiraConfig,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["jira-config"] });
      setForm({});
      setToast({ msg: "Jira configuration saved", type: "success" });
    },
    onError: () => setToast({ msg: "Failed to save Jira configuration", type: "error" }),
  });

  const jiraTestMut = useMutation({
    mutationFn: testJiraConnection,
    onSuccess: (data) => {
      if (data.status === "ok") {
        setJiraTestResult({ connectedAs: data.connected_as ?? "", url: data.jira_url ?? "" });
        setJiraTestError(null);
      } else {
        setJiraTestError((data as { message?: string }).message ?? "Connection failed");
        setJiraTestResult(null);
      }
    },
    onError: (err: Error) => {
      setJiraTestError(err.message || "Connection failed");
      setJiraTestResult(null);
    },
  });

  const tempoTestMut = useMutation({
    mutationFn: testTempoConnection,
    onSuccess: (data) => {
      if (data.status === "ok") {
        setTempoTestResult(data.message ?? "Connected");
        setTempoTestError(null);
      } else {
        setTempoTestError(data.message ?? "Tempo test failed");
        setTempoTestResult(null);
      }
    },
    onError: (err: Error) => {
      setTempoTestError(err.message || "Tempo test failed");
      setTempoTestResult(null);
    },
  });

  if (isLoading) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
      </div>
    );
  }

  return (
    <>
      {toast && (
        <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />
      )}
      <div className="space-y-4">
        <ToggleRow
          label="Enable Jira Integration"
          description="Automatically create and update Jira tickets for tests"
          checked={Boolean(form.enabled !== undefined ? form.enabled : cfg?.enabled)}
          onChange={(v) => setForm((prev) => ({ ...prev, enabled: v }))}
        />

        <div className="grid grid-cols-2 gap-4 pt-2">
          <div className="col-span-2">
            <label className="mb-1 block text-xs font-medium text-cyan-400">Jira URL</label>
            <input
              type="text"
              value={String(form.url !== undefined ? form.url : (cfg?.url ?? ""))}
              onChange={(e) => setForm((prev) => ({ ...prev, url: e.target.value }))}
              placeholder="https://yourcompany.atlassian.net"
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
            />
            <p className="mt-1 text-xs text-gray-600">Base URL of your Jira instance</p>
          </div>

          <div>
            <label className="mb-1 block text-xs font-medium text-cyan-400">Default Project Key</label>
            <input
              type="text"
              value={String(form.project_key !== undefined ? form.project_key : (cfg?.project_key ?? ""))}
              onChange={(e) => setForm((prev) => ({ ...prev, project_key: e.target.value }))}
              placeholder="SEC"
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
            />
            <p className="mt-1 text-xs text-gray-600">Jira project where test tickets will be created</p>
          </div>

          <div>
            <label className="mb-1 block text-xs font-medium text-cyan-400">Parent Ticket (optional)</label>
            <input
              type="text"
              value={String(form.parent_ticket !== undefined ? form.parent_ticket : (cfg?.parent_ticket ?? ""))}
              onChange={(e) => setForm((prev) => ({ ...prev, parent_ticket: e.target.value }))}
              placeholder="OFS-20795"
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
            />
            <p className="mt-1 text-xs text-gray-600">Campaigns are created directly under this issue</p>
          </div>

          <div>
            <label className="mb-1 block text-xs font-medium text-cyan-400">Standalone Tests Parent Ticket (optional)</label>
            <input
              type="text"
              value={String(form.parent_ticket_standalone !== undefined ? form.parent_ticket_standalone : (cfg?.parent_ticket_standalone ?? ""))}
              onChange={(e) => setForm((prev) => ({ ...prev, parent_ticket_standalone: e.target.value }))}
              placeholder="OFS-20798"
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
            />
            <p className="mt-1 text-xs text-gray-600">
              Standalone tests are nested here. Falls back to Campaign Parent if not set.
            </p>
          </div>
        </div>

        {/* ── Admin account (replaces per-user tokens) ───────────── */}
        <div className="mt-2 border-t border-gray-800 pt-4">
          <p className="text-sm font-semibold text-gray-300 mb-1">Admin Jira Account</p>
          <p className="text-xs text-gray-500 mb-4">
            One admin account handles all Jira and Tempo operations. Regular users need zero configuration — their Atlassian account ID is auto-detected on login.
          </p>

          <div className="space-y-3">
            <div>
              <label className="mb-1 block text-xs font-medium text-cyan-400">Admin Email</label>
              <input
                type="email"
                value={String(form.admin_email !== undefined ? form.admin_email : "")}
                onChange={(e) => setForm((prev) => ({ ...prev, admin_email: e.target.value }))}
                placeholder="jira-admin@company.com"
                className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
              />
              <div className="mt-1 flex items-center gap-2">
                {cfg?.admin_email_set ? (
                  <span className="inline-flex items-center gap-1 rounded-full bg-emerald-900/50 px-2 py-0.5 text-[11px] font-medium text-emerald-400">
                    <CheckCircle className="h-3 w-3" /> Configured
                  </span>
                ) : (
                  <span className="inline-flex items-center gap-1 rounded-full bg-amber-900/50 px-2 py-0.5 text-[11px] font-medium text-amber-400">
                    <AlertCircle className="h-3 w-3" /> Not configured
                  </span>
                )}
                <span className="text-[11px] text-gray-600">Leave blank to keep current</span>
              </div>
            </div>

            <div>
              <label className="mb-1 block text-xs font-medium text-cyan-400">Admin Jira API Token</label>
              <div className="relative">
                <input
                  type={showAdminToken ? "text" : "password"}
                  value={String(form.admin_api_token !== undefined ? form.admin_api_token : "")}
                  onChange={(e) => setForm((prev) => ({ ...prev, admin_api_token: e.target.value }))}
                  placeholder={cfg?.admin_email_set ? "Leave blank to keep current token" : "Paste Atlassian API token here"}
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 pr-10 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
                />
                <button
                  type="button"
                  onClick={() => setShowAdminToken(!showAdminToken)}
                  className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-300"
                >
                  {showAdminToken ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                </button>
              </div>
              <p className="mt-1 text-[11px] text-gray-600">
                Create at{" "}
                <a
                  href="https://id.atlassian.com/manage-profile/security/api-tokens"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-cyan-500 hover:text-cyan-400 underline"
                >
                  id.atlassian.com →
                </a>
              </p>
            </div>

            <div>
              <label className="mb-1 block text-xs font-medium text-purple-400">Admin Tempo API Token</label>
              <div className="relative">
                <input
                  type={showTempoToken ? "text" : "password"}
                  value={String(form.tempo_admin_token !== undefined ? form.tempo_admin_token : "")}
                  onChange={(e) => setForm((prev) => ({ ...prev, tempo_admin_token: e.target.value }))}
                  placeholder={cfg?.tempo_admin_token_set ? "Leave blank to keep current token" : "Paste Tempo API token here"}
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 pr-10 text-sm text-gray-200 placeholder-gray-600 focus:border-purple-500 focus:outline-none"
                />
                <button
                  type="button"
                  onClick={() => setShowTempoToken(!showTempoToken)}
                  className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-300"
                >
                  {showTempoToken ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                </button>
              </div>
              <div className="mt-1 flex items-center gap-2">
                {cfg?.tempo_admin_token_set ? (
                  <span className="inline-flex items-center gap-1 rounded-full bg-emerald-900/50 px-2 py-0.5 text-[11px] font-medium text-emerald-400">
                    <CheckCircle className="h-3 w-3" /> Configured
                  </span>
                ) : (
                  <span className="inline-flex items-center gap-1 rounded-full bg-amber-900/50 px-2 py-0.5 text-[11px] font-medium text-amber-400">
                    <AlertCircle className="h-3 w-3" /> Not configured
                  </span>
                )}
                <span className="text-[11px] text-gray-600">
                  Jira → Apps → Tempo → Settings → API Integration
                </span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex items-center gap-3 pt-2">
          <button
            onClick={() => {
              if (Object.keys(form).length > 0) saveMut.mutate(form);
            }}
            disabled={saveMut.isPending || Object.keys(form).length === 0}
            className="flex items-center gap-2 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
          >
            {saveMut.isPending ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Save className="h-4 w-4" />
            )}
            Save Configuration
          </button>
        </div>

        {/* ── Test connections ───────────────────────────────────── */}
        <div className="grid grid-cols-2 gap-3 pt-1">
          <div className="rounded-lg border border-gray-700 bg-gray-800/50 p-3 space-y-2">
            <p className="text-xs font-medium text-gray-400">Test Jira connection</p>
            <button
              onClick={() => {
                setJiraTestResult(null);
                setJiraTestError(null);
                jiraTestMut.mutate();
              }}
              disabled={jiraTestMut.isPending || !cfg?.admin_email_set}
              className="flex items-center gap-2 rounded-lg border border-cyan-700 px-3 py-1.5 text-sm font-medium text-cyan-400 hover:bg-cyan-900/30 disabled:opacity-50 transition-colors"
            >
              {jiraTestMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <TestTube className="h-4 w-4" />}
              Test Jira
            </button>
            {jiraTestResult && (
              <div className="flex items-center gap-2 rounded-md bg-emerald-900/30 border border-emerald-800/50 px-3 py-2 text-xs text-emerald-300">
                <CheckCircle className="h-3.5 w-3.5 shrink-0" />
                Connected as: {jiraTestResult.connectedAs}
              </div>
            )}
            {jiraTestError && (
              <div className="flex items-center gap-2 rounded-md bg-red-900/30 border border-red-800/50 px-3 py-2 text-xs text-red-300">
                <XCircle className="h-3.5 w-3.5 shrink-0" />
                {jiraTestError}
              </div>
            )}
          </div>

          <div className="rounded-lg border border-gray-700 bg-gray-800/50 p-3 space-y-2">
            <p className="text-xs font-medium text-gray-400">Test Tempo connection</p>
            <button
              onClick={() => {
                setTempoTestResult(null);
                setTempoTestError(null);
                tempoTestMut.mutate();
              }}
              disabled={tempoTestMut.isPending || !cfg?.tempo_admin_token_set}
              className="flex items-center gap-2 rounded-lg border border-purple-700 px-3 py-1.5 text-sm font-medium text-purple-400 hover:bg-purple-900/30 disabled:opacity-50 transition-colors"
            >
              {tempoTestMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <TestTube className="h-4 w-4" />}
              Test Tempo
            </button>
            {tempoTestResult && (
              <div className="flex items-center gap-2 rounded-md bg-emerald-900/30 border border-emerald-800/50 px-3 py-2 text-xs text-emerald-300">
                <CheckCircle className="h-3.5 w-3.5 shrink-0" />
                {tempoTestResult}
              </div>
            )}
            {tempoTestError && (
              <div className="flex items-center gap-2 rounded-md bg-red-900/30 border border-red-800/50 px-3 py-2 text-xs text-red-300">
                <XCircle className="h-3.5 w-3.5 shrink-0" />
                {tempoTestError}
              </div>
            )}
          </div>
        </div>
      </div>
    </>
  );
}

// ---------------------------------------------------------------------------
// SSO / Azure AD Config Section (admin only)
// ---------------------------------------------------------------------------

const AZURE_ROLES = [
  { value: "admin",     label: "Aegis Admin",     desc: "Full platform access including system settings" },
  { value: "red_lead",  label: "Aegis Red Lead",  desc: "Red team lead — manage tests, campaigns and templates" },
  { value: "blue_lead", label: "Aegis Blue Lead", desc: "Blue team lead — validate tests and manage coverage" },
  { value: "manager",   label: "Aegis Manager",   desc: "Approves campaigns and campaign changes" },
  { value: "red_tech",  label: "Aegis Red Tech",  desc: "Red team technician — execute tests" },
  { value: "blue_tech", label: "Aegis Blue Tech", desc: "Blue team technician — review detections" },
  { value: "viewer",    label: "Aegis Viewer",    desc: "Read-only access to dashboards and reports" },
];

function CopyFieldSSO({ value, label }: { value: string; label: string }) {
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard.writeText(value).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  return (
    <div>
      <label className="mb-1 block text-xs font-medium text-gray-400">{label}</label>
      <div className="flex items-center gap-2">
        <code className="flex-1 truncate rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-cyan-300 font-mono">
          {value || <span className="text-gray-600 italic">not set</span>}
        </code>
        <button
          type="button"
          onClick={copy}
          disabled={!value}
          className="flex-shrink-0 rounded-lg border border-gray-700 bg-gray-800 p-2 text-gray-400 transition-colors hover:text-white disabled:opacity-40"
          title="Copy"
        >
          {copied ? <CheckCircle className="h-3.5 w-3.5 text-green-400" /> : <Copy className="h-3.5 w-3.5" />}
        </button>
      </div>
    </div>
  );
}

function SsoConfigSection() {
  const qc = useQueryClient();
  const origin = typeof window !== "undefined" ? window.location.origin : "";
  const defaultSpEntityId = `${origin}/api/v1/sso/metadata`;
  const defaultSpAcsUrl   = `${origin}/api/v1/sso/callback`;

  const { data: existingConfig, isLoading: configLoading } = useQuery<SsoConfig | null>({
    queryKey: ["sso-config"],
    queryFn: async () => {
      try { return await getSsoConfig(); } catch { return null; }
    },
  });

  const [tenantId, setTenantId] = useState("");
  const [form, setForm] = useState<SsoConfigUpdate>({
    is_enabled:      false,
    provider_name:   "Azure AD / Entra ID",
    sp_entity_id:    defaultSpEntityId,
    sp_acs_url:      defaultSpAcsUrl,
    idp_entity_id:   "",
    idp_sso_url:     "",
    idp_certificate: "",
    attr_email:      "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
    attr_username:   "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
    attr_role:       "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
    default_role:    "viewer",
    auto_provision:  true,
  });
  const [formLoaded, setFormLoaded] = useState(false);
  const [saveSuccess, setSaveSuccess] = useState(false);

  if (existingConfig && !formLoaded) {
    setForm({
      is_enabled:      existingConfig.is_enabled,
      provider_name:   existingConfig.provider_name   ?? "Azure AD / Entra ID",
      sp_entity_id:    existingConfig.sp_entity_id    ?? defaultSpEntityId,
      sp_acs_url:      existingConfig.sp_acs_url       ?? defaultSpAcsUrl,
      idp_entity_id:   existingConfig.idp_entity_id   ?? "",
      idp_sso_url:     existingConfig.idp_sso_url      ?? "",
      idp_certificate: existingConfig.idp_certificate ?? "",
      attr_email:      existingConfig.attr_email       ?? "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
      attr_username:   existingConfig.attr_username    ?? "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
      attr_role:       existingConfig.attr_role        ?? "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
      default_role:    existingConfig.default_role     ?? "viewer",
      auto_provision:  existingConfig.auto_provision   ?? true,
    });
    if (existingConfig.idp_sso_url) {
      const m = existingConfig.idp_sso_url.match(/microsoftonline\.com\/([^/]+)\//);
      if (m) setTenantId(m[1]);
    }
    setFormLoaded(true);
  }

  const handleTenantChange = (val: string) => {
    setTenantId(val);
    if (val.trim()) {
      setForm((f) => ({
        ...f,
        idp_entity_id: `https://sts.windows.net/${val.trim()}/`,
        idp_sso_url:   `https://login.microsoftonline.com/${val.trim()}/saml2`,
      }));
    }
  };

  const saveMutation = useMutation({
    mutationFn: (payload: SsoConfigUpdate) => updateSsoConfig(payload),
    onSuccess: () => {
      setSaveSuccess(true);
      setTimeout(() => setSaveSuccess(false), 4000);
      qc.invalidateQueries({ queryKey: ["sso-config"] });
      qc.invalidateQueries({ queryKey: ["sso-status"] });
    },
  });

  const handleSave = (e: React.FormEvent) => { e.preventDefault(); saveMutation.mutate(form); };
  const isConfigured = !!(form.idp_entity_id && form.idp_sso_url && form.idp_certificate);

  return (
    <div className="rounded-xl border border-indigo-500/30 bg-gray-900 p-6">
      <div className="flex flex-wrap items-start justify-between gap-4 mb-6">
        <div className="flex items-start gap-4">
          <div className="rounded-lg bg-indigo-500/10 p-3 mt-0.5">
            <KeyRound className="h-6 w-6 text-indigo-400" />
          </div>
          <div>
            <h2 className="text-lg font-semibold text-white">Azure AD / Entra ID SSO</h2>
            <p className="mt-1 text-sm text-gray-400 max-w-2xl">
              Delegate authentication to Azure Active Directory via SAML 2.0.
              Users sign in with corporate credentials; roles assigned automatically via Azure App Roles.
            </p>
          </div>
        </div>
        <span className={`inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium ${
          form.is_enabled && isConfigured
            ? "border-green-500/40 bg-green-900/20 text-green-400"
            : "border-gray-600 bg-gray-800/50 text-gray-400"
        }`}>
          {form.is_enabled && isConfigured
            ? <><CheckCircle className="h-3 w-3" /> Active</>
            : <><XCircle className="h-3 w-3" /> {isConfigured ? "Disabled" : "Not configured"}</>}
        </span>
      </div>

      {configLoading ? (
        <div className="flex justify-center py-8"><Loader2 className="h-6 w-6 animate-spin text-indigo-400" /></div>
      ) : (
        <form onSubmit={handleSave} className="space-y-8">
          {/* Step 1 */}
          <div>
            <div className="mb-3 flex items-center gap-2">
              <span className="flex h-6 w-6 items-center justify-center rounded-full bg-indigo-600 text-xs font-bold text-white">1</span>
              <h3 className="text-sm font-semibold text-white">Give these values to your IT team</h3>
            </div>
            <div className="space-y-3 rounded-lg border border-gray-700 bg-gray-800/30 p-4">
              <CopyFieldSSO label="Entity ID (Identifier)" value={form.sp_entity_id ?? defaultSpEntityId} />
              <CopyFieldSSO label="Reply URL (Assertion Consumer Service)" value={form.sp_acs_url ?? defaultSpAcsUrl} />
              <div className="pt-1">
                <a href="/api/v1/sso/metadata" target="_blank" rel="noopener noreferrer"
                  className="inline-flex items-center gap-1.5 rounded-lg border border-indigo-500/30 bg-indigo-900/20 px-3 py-1.5 text-xs font-medium text-indigo-400 transition-colors hover:bg-indigo-900/40">
                  <Download className="h-3.5 w-3.5" /> Download SP Metadata XML
                </a>
              </div>
            </div>
          </div>

          {/* Step 2 */}
          <div>
            <div className="mb-3 flex items-center gap-2">
              <span className="flex h-6 w-6 items-center justify-center rounded-full bg-indigo-600 text-xs font-bold text-white">2</span>
              <h3 className="text-sm font-semibold text-white">Create App Roles in Azure</h3>
            </div>
            <div className="overflow-x-auto rounded-lg border border-gray-700 bg-gray-800/30">
              <table className="w-full text-left text-xs">
                <thead>
                  <tr className="border-b border-gray-700">
                    <th className="px-4 py-2.5 font-semibold text-gray-400">Display Name</th>
                    <th className="px-4 py-2.5 font-semibold text-gray-400">Value (exact)</th>
                    <th className="px-4 py-2.5 font-semibold text-gray-400">Description</th>
                  </tr>
                </thead>
                <tbody>
                  {AZURE_ROLES.map((r) => (
                    <tr key={r.value} className="border-b border-gray-700/50 hover:bg-gray-700/20">
                      <td className="px-4 py-2.5 text-gray-200">{r.label}</td>
                      <td className="px-4 py-2.5"><code className="rounded bg-gray-800 px-1.5 py-0.5 text-indigo-300 font-mono">{r.value}</code></td>
                      <td className="px-4 py-2.5 text-gray-400">{r.desc}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          {/* Step 3 */}
          <div>
            <div className="mb-3 flex items-center gap-2">
              <span className="flex h-6 w-6 items-center justify-center rounded-full bg-indigo-600 text-xs font-bold text-white">3</span>
              <h3 className="text-sm font-semibold text-white">Enter Azure tenant details</h3>
            </div>
            <div className="space-y-4 rounded-lg border border-gray-700 bg-gray-800/30 p-4">
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">Tenant ID <span className="text-gray-500">(auto-fills fields below)</span></label>
                <input type="text" value={tenantId} onChange={(e) => handleTenantChange(e.target.value)}
                  placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-indigo-500 focus:outline-none font-mono" />
                <p className="mt-1 text-xs text-gray-500">Azure AD → Overview → Tenant ID</p>
              </div>
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">IdP Entity ID <span className="text-red-400">*</span></label>
                <input type="text" value={form.idp_entity_id ?? ""} onChange={(e) => setForm({ ...form, idp_entity_id: e.target.value })}
                  placeholder="https://sts.windows.net/{tenant-id}/"
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-indigo-500 focus:outline-none font-mono" />
              </div>
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">SSO URL <span className="text-red-400">*</span></label>
                <input type="text" value={form.idp_sso_url ?? ""} onChange={(e) => setForm({ ...form, idp_sso_url: e.target.value })}
                  placeholder="https://login.microsoftonline.com/{tenant-id}/saml2"
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-indigo-500 focus:outline-none font-mono" />
              </div>
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">Display name <span className="text-gray-500">(shown on login page)</span></label>
                <input type="text" value={form.provider_name ?? ""} onChange={(e) => setForm({ ...form, provider_name: e.target.value })}
                  placeholder="Azure AD / Entra ID"
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-indigo-500 focus:outline-none" />
              </div>
            </div>
          </div>

          {/* Step 4 */}
          <div>
            <div className="mb-3 flex items-center gap-2">
              <span className="flex h-6 w-6 items-center justify-center rounded-full bg-indigo-600 text-xs font-bold text-white">4</span>
              <h3 className="text-sm font-semibold text-white">Paste IdP certificate</h3>
            </div>
            <textarea value={form.idp_certificate ?? ""} onChange={(e) => setForm({ ...form, idp_certificate: e.target.value })}
              placeholder={"-----BEGIN CERTIFICATE-----\nMIIC...base64...\n-----END CERTIFICATE-----"}
              rows={5}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-gray-300 placeholder-gray-500 focus:border-indigo-500 focus:outline-none font-mono" />
            <p className="mt-1 text-xs text-gray-500">Azure AD → Enterprise App → Single sign-on → SAML Signing Certificate → Download Base64</p>
          </div>

          {/* Step 5 */}
          <div>
            <div className="mb-3 flex items-center gap-2">
              <span className="flex h-6 w-6 items-center justify-center rounded-full bg-indigo-600 text-xs font-bold text-white">5</span>
              <h3 className="text-sm font-semibold text-white">Attribute mapping</h3>
              <span className="text-xs text-gray-500">(pre-filled with Azure AD defaults)</span>
            </div>
            <div className="space-y-3 rounded-lg border border-gray-700 bg-gray-800/30 p-4">
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">Email attribute</label>
                <input type="text" value={form.attr_email ?? ""} onChange={(e) => setForm({ ...form, attr_email: e.target.value })}
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-gray-300 focus:border-indigo-500 focus:outline-none font-mono" />
              </div>
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">Username attribute</label>
                <input type="text" value={form.attr_username ?? ""} onChange={(e) => setForm({ ...form, attr_username: e.target.value })}
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-gray-300 focus:border-indigo-500 focus:outline-none font-mono" />
              </div>
              <div>
                <label className="mb-1 block text-xs font-medium text-gray-300">Role attribute</label>
                <input type="text" value={form.attr_role ?? ""} onChange={(e) => setForm({ ...form, attr_role: e.target.value })}
                  className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-gray-300 focus:border-indigo-500 focus:outline-none font-mono" />
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="mb-1 block text-xs font-medium text-gray-300">Default role</label>
                  <select value={form.default_role ?? "viewer"} onChange={(e) => setForm({ ...form, default_role: e.target.value })}
                    className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 focus:border-indigo-500 focus:outline-none">
                    {AZURE_ROLES.map((r) => <option key={r.value} value={r.value}>{r.label}</option>)}
                  </select>
                </div>
                <div className="flex items-end pb-0.5">
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" checked={form.auto_provision ?? true}
                      onChange={(e) => setForm({ ...form, auto_provision: e.target.checked })}
                      className="h-4 w-4 rounded accent-indigo-500" />
                    <span className="text-sm text-gray-300">Auto-provision new users</span>
                  </label>
                </div>
              </div>
            </div>
          </div>

          {/* Enable + Save */}
          <div className="flex flex-wrap items-center justify-between gap-4 rounded-lg border border-gray-700 bg-gray-800/30 p-4">
            <label className="flex items-center gap-3 cursor-pointer">
              <div onClick={() => setForm((f) => ({ ...f, is_enabled: !f.is_enabled }))}
                className={`relative h-6 w-11 rounded-full transition-colors ${form.is_enabled ? "bg-indigo-600" : "bg-gray-600"}`}>
                <span className={`absolute top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform ${form.is_enabled ? "translate-x-5" : "translate-x-0.5"}`} />
              </div>
              <span className="text-sm font-medium text-gray-200">
                {form.is_enabled ? "SSO enabled — Azure AD is primary login" : "SSO disabled — local login only"}
              </span>
            </label>
            <div className="flex items-center gap-3">
              {saveSuccess && <span className="flex items-center gap-1.5 text-sm text-green-400"><CheckCircle className="h-4 w-4" /> Saved</span>}
              {saveMutation.isError && <span className="text-sm text-red-400">{(saveMutation.error as Error)?.message ?? "Save failed"}</span>}
              <button type="submit" disabled={saveMutation.isPending || !isConfigured}
                className="flex items-center gap-2 rounded-lg bg-indigo-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-indigo-500 disabled:opacity-50"
                title={!isConfigured ? "Fill in IdP Entity ID, SSO URL, and Certificate first" : undefined}>
                {saveMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Building2 className="h-4 w-4" />}
                {saveMutation.isPending ? "Saving…" : "Save configuration"}
              </button>
            </div>
          </div>
        </form>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Export / Import Configuration (admin only)
// ---------------------------------------------------------------------------

function ExportImportSection() {
  const fileRef = useRef<HTMLInputElement>(null);
  const [importing, setImporting] = useState(false);
  const [importResult, setImportResult] = useState<{
    status: string;
    summary: Record<string, number>;
    warnings: string[];
  } | null>(null);
  const [importError, setImportError] = useState<string | null>(null);

  const handleExport = async () => {
    try {
      const resp = await client.get("/admin/export-config", { responseType: "blob" });
      const url = URL.createObjectURL(resp.data);
      const a = document.createElement("a");
      a.href = url;
      a.download = `aegis-config-${new Date().toISOString().slice(0, 10)}.json`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (e) {
      alert("Export failed: " + (e as Error).message);
    }
  };

  const handleImportFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    e.target.value = "";
    setImportError(null);
    setImportResult(null);
    setImporting(true);
    try {
      const json = JSON.parse(await file.text());
      const resp = await client.post("/admin/import-config", json);
      setImportResult(resp.data);
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail ??
        (err as Error)?.message ?? "Import failed";
      setImportError(String(msg));
    } finally {
      setImporting(false);
    }
  };

  return (
    <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
      <div className="flex items-center gap-2 mb-1">
        <PackageOpen className="h-5 w-5 text-cyan-400" />
        <h2 className="text-lg font-semibold text-white">Configuration Export / Import</h2>
      </div>
      <p className="mb-5 text-sm text-gray-400">
        Export platform configuration to JSON for backup or migration. Import restores settings,
        webhooks, templates and users on a fresh instance.
      </p>
      <div className="mb-5 rounded-lg border border-gray-800 bg-gray-800/30 p-4">
        <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-gray-500">What is included</p>
        <div className="grid gap-x-8 gap-y-1 text-xs text-gray-400 sm:grid-cols-2">
          {[
            ["✅", "Email & Jira settings"],
            ["✅", "SSO / SAML configuration"],
            ["✅", "Webhooks"],
            ["✅", "Scoring weights"],
            ["✅", "Custom test templates"],
            ["✅", "Users (roles & status)"],
            ["🔒", "Passwords / API tokens → REDACTED"],
            ["❌", "Tests, campaigns, techniques data"],
          ].map(([icon, text]) => (
            <div key={text} className="flex items-center gap-1.5"><span>{icon}</span><span>{text}</span></div>
          ))}
        </div>
      </div>
      <div className="flex flex-wrap gap-3">
        <button onClick={handleExport}
          className="flex items-center gap-2 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 transition-colors">
          <Download className="h-4 w-4" /> Export Configuration
        </button>
        <input ref={fileRef} type="file" accept=".json" onChange={handleImportFile} className="hidden" />
        <button onClick={() => fileRef.current?.click()} disabled={importing}
          className="flex items-center gap-2 rounded-lg border border-gray-700 bg-gray-800 px-4 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 disabled:opacity-50 transition-colors">
          {importing ? <Loader2 className="h-4 w-4 animate-spin" /> : <Upload className="h-4 w-4" />}
          {importing ? "Importing…" : "Import Configuration"}
        </button>
      </div>
      {importResult && (
        <div className="mt-4 rounded-lg border border-green-500/30 bg-green-500/5 p-4 space-y-2">
          <p className="text-sm font-medium text-green-400 flex items-center gap-2">
            <CheckCircle className="h-4 w-4" /> Import completed successfully
          </p>
          <div className="grid gap-2 text-xs text-gray-400 sm:grid-cols-3">
            {Object.entries(importResult.summary).map(([key, val]) => (
              <div key={key} className="flex items-center justify-between rounded bg-gray-800 px-2 py-1">
                <span className="capitalize">{key.replace(/_/g, " ")}</span>
                <span className="font-mono text-cyan-400">{val}</span>
              </div>
            ))}
          </div>
          {importResult.warnings.length > 0 && (
            <ul className="mt-2 space-y-0.5 text-[11px] text-amber-400/80 list-disc list-inside">
              {importResult.warnings.map((w) => <li key={w}>{w}</li>)}
            </ul>
          )}
        </div>
      )}
      {importError && (
        <div className="mt-4 rounded-lg border border-red-500/30 bg-red-900/20 p-3 text-sm text-red-400">⚠ {importError}</div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// System Information + Version (admin only)
// ---------------------------------------------------------------------------

function SystemInfoSection() {
  return (
    <div className="space-y-4">
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <h2 className="mb-4 text-lg font-semibold text-white flex items-center gap-2">
          <ShieldCheck className="h-5 w-5 text-cyan-400" /> System Status
        </h2>
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
          {[
            { icon: Server,    label: "Backend",       value: "Online",     color: "text-green-400" },
            { icon: Database,  label: "PostgreSQL",    value: "Connected",  color: "text-green-400" },
            { icon: HardDrive, label: "MinIO Storage", value: "Available",  color: "text-green-400" },
            { icon: Clock,     label: "Scheduler",     value: "Running",    color: "text-green-400" },
          ].map(({ icon: Icon, label, value, color }) => (
            <div key={label} className="rounded-lg border border-gray-800 bg-gray-800/50 p-4">
              <div className="flex items-center gap-3">
                <Icon className={`h-5 w-5 ${color}`} />
                <div>
                  <p className="text-xs font-medium uppercase text-gray-500">{label}</p>
                  <p className={`text-sm font-medium ${color}`}>{value}</p>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>

      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <h2 className="mb-4 text-lg font-semibold text-white">Version Information</h2>
        <dl className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4 text-sm">
          <div><dt className="text-xs font-medium uppercase text-gray-500">Platform</dt><dd className="mt-1 text-gray-300">Aegis v0.1.0</dd></div>
          <div><dt className="text-xs font-medium uppercase text-gray-500">Backend</dt><dd className="mt-1 text-gray-300">FastAPI + Python 3.11</dd></div>
          <div><dt className="text-xs font-medium uppercase text-gray-500">Frontend</dt><dd className="mt-1 text-gray-300">React 19 + TypeScript</dd></div>
          <div><dt className="text-xs font-medium uppercase text-gray-500">Database</dt><dd className="mt-1 text-gray-300">PostgreSQL 15</dd></div>
        </dl>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main SettingsPage
// ---------------------------------------------------------------------------

type Tab = "profile" | "notifications" | "webhooks" | "email" | "jira" | "sso" | "system";

export default function SettingsPage() {
  const { user } = useAuth();
  const role = user?.role ?? "viewer";
  const isAdmin = role === "admin";
  const isLead = ["admin", "red_lead", "blue_lead"].includes(role);

  const [activeTab, setActiveTab] = useState<Tab>("profile");

  const tabs: { id: Tab; label: string; icon: React.FC<{ className?: string }>; show: boolean }[] =
    [
      { id: "profile", label: "Profile", icon: User, show: true },
      { id: "notifications", label: "Notifications", icon: Bell, show: true },
      {
        id: "webhooks",
        label: "Webhooks",
        icon: Webhook,
        show: isLead,
      },
      { id: "email", label: "Email / SMTP", icon: Mail, show: isAdmin },
      { id: "jira", label: "Jira", icon: Link2, show: isAdmin },
      { id: "sso", label: "SSO / Azure AD", icon: KeyRound, show: isAdmin },
      { id: "system", label: "System", icon: Server, show: isAdmin },
    ];

  const visibleTabs = tabs.filter((t) => t.show);

  return (
    <div className="min-h-screen bg-gray-950 px-6 py-8">
      <div className="mx-auto max-w-4xl">
        {/* Header */}
        <div className="mb-8 flex items-center gap-3">
          <Settings className="h-7 w-7 text-cyan-400" />
          <div>
            <h1 className="text-2xl font-bold text-white">Settings</h1>
            <p className="text-sm text-gray-500">
              Manage your preferences, integrations, and system configuration
            </p>
          </div>
        </div>

        <div className="flex gap-6">
          {/* Sidebar tabs */}
          <nav className="w-44 shrink-0 space-y-1">
            {visibleTabs.map((tab) => (
              <button
                key={tab.id}
                onClick={() => setActiveTab(tab.id)}
                className={`flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors ${
                  activeTab === tab.id
                    ? "bg-cyan-500/10 text-cyan-400"
                    : "text-gray-400 hover:bg-gray-800 hover:text-gray-200"
                }`}
              >
                <tab.icon className="h-4 w-4" />
                {tab.label}
              </button>
            ))}
          </nav>

          {/* Content */}
          <div className="flex-1">
            {activeTab === "profile" && (
              <Section title="Profile & Jira" icon={User}>
                <ProfileSection />
              </Section>
            )}
            {activeTab === "notifications" && (
              <Section title="Notification Preferences" icon={Bell}>
                <NotificationSection />
              </Section>
            )}
            {activeTab === "webhooks" && isLead && (
              <Section title="Webhook Configuration" icon={Webhook}>
                <WebhooksSection />
              </Section>
            )}
            {activeTab === "email" && isAdmin && (
              <Section title="Email / SMTP Configuration" icon={Mail}>
                <EmailSection />
              </Section>
            )}
            {activeTab === "jira" && isAdmin && (
              <Section title="Jira Integration" icon={Link2}>
                <JiraConfigSection />
              </Section>
            )}
            {activeTab === "sso" && isAdmin && (
              <SsoConfigSection />
            )}
            {activeTab === "system" && isAdmin && (
              <div className="space-y-6">
                <SystemInfoSection />
                <ExportImportSection />
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
