"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import clsx from "clsx";
import { Building2, GripVertical, Layers3, RefreshCw, Shield, Users, WalletCards } from "lucide-react";
import { useRouter } from "next/navigation";
import { ChangeEvent, DragEvent, FormEvent, useEffect, useMemo, useState } from "react";
import { api } from "@/lib/api";
import { siteConfig } from "@/lib/site-config";
import { DEFAULT_TIME_ZONE } from "@/lib/time-zone";
import type { AppConfig, BillingProviderInfo, InvoiceRecord, MailMigrationJob, Mailbox, Organization, Subscription } from "@/lib/types";
import { InstallSetupPanel } from "./install-setup-panel";
import { BrandLogo } from "./brand-logo";

type CreateOrgForm = {
  name: string;
  primary_domain: string;
  timezone: string;
  plan_code: string;
  billing_provider: string;
};

type BulkMigrationRowState = {
  id: string;
  mailbox_email: string;
  mailbox_password: string;
  label: string;
  source_host: string;
  source_port: string;
  source_security: "ssl" | "starttls" | "plain";
  source_skip_ssl_verify: boolean;
  source_username: string;
  source_password: string;
  include_folders: string;
  exclude_folders: string;
};

type BulkMigrationTestResult = {
  row_id: string;
  mailbox_email: string;
  ok: boolean;
  message: string;
};

type BulkMigrationActivity = {
  mode: "idle" | "testing" | "queueing";
  row_id: string;
  index: number;
  total: number;
};

type BulkMigrationJob = {
  row_id: string;
  mailbox_email: string;
  mailbox_password: string;
  label?: string;
  source_host: string;
  source_port: number;
  source_security: "ssl" | "starttls" | "plain";
  source_skip_ssl_verify?: boolean;
  source_username: string;
  source_password: string;
  dry_run?: boolean;
  include_folders?: string[];
  exclude_folders?: string[];
};

type BulkMigrationPreset = {
  id: "gmail_basic" | "gmail_cutover" | "outlook_basic" | "outlook_cutover" | "imap";
  label: string;
  source_host?: string;
  source_port?: string;
  source_security: BulkMigrationRowState["source_security"];
  include_folders?: string;
  exclude_folders?: string;
  description: string;
};

const BULK_MIGRATION_DEFAULT_EXCLUDES = "Trash,Junk,Spam";
const BULK_MIGRATION_PRESETS: BulkMigrationPreset[] = [
  {
    id: "gmail_basic",
    label: "Gmail",
    source_host: "imap.gmail.com",
    source_port: "993",
    source_security: "ssl",
    include_folders: "Inbox,Sent Mail",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    description: "Best fit for Gmail and Google Workspace accounts.",
  },
  {
    id: "gmail_cutover",
    label: "Gmail cutover",
    source_host: "imap.gmail.com",
    source_port: "993",
    source_security: "ssl",
    include_folders: "Inbox,Sent Mail,Drafts",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    description: "Includes the common Gmail working folders for a live cutover.",
  },
  {
    id: "outlook_basic",
    label: "Outlook 365",
    source_host: "outlook.office365.com",
    source_port: "993",
    source_security: "ssl",
    include_folders: "Inbox,Sent Items",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    description: "Use for Microsoft 365 / Outlook IMAP access.",
  },
  {
    id: "outlook_cutover",
    label: "Outlook cutover",
    source_host: "outlook.office365.com",
    source_port: "993",
    source_security: "ssl",
    include_folders: "Inbox,Sent Items,Drafts,Archive",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    description: "Adds common working folders for a live Microsoft 365 cutover.",
  },
  {
    id: "imap",
    label: "Generic IMAP",
    source_port: "993",
    source_security: "ssl",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    description: "Use for standard IMAP servers when you already know the host.",
  },
];

function createBulkMigrationRow(overrides: Partial<BulkMigrationRowState> = {}): BulkMigrationRowState {
  const id = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `row_${Math.random().toString(36).slice(2, 10)}`;
  return {
    id,
    mailbox_email: "",
    mailbox_password: "",
    label: "",
    source_host: "",
    source_port: "993",
    source_security: "ssl",
    source_skip_ssl_verify: true,
    source_username: "",
    source_password: "",
    include_folders: "",
    exclude_folders: BULK_MIGRATION_DEFAULT_EXCLUDES,
    ...overrides,
  };
}

type AdminConsoleProps = {
  initialAdminKey?: string;
};

export function AdminConsole({ initialAdminKey = "" }: AdminConsoleProps) {
  const queryClient = useQueryClient();
  const router = useRouter();
  const [adminKey, setAdminKey] = useState(initialAdminKey);
  const [selectedOrgId, setSelectedOrgId] = useState("");
  const [newOrg, setNewOrg] = useState<CreateOrgForm>({
    name: "",
    primary_domain: "",
    timezone: DEFAULT_TIME_ZONE,
    plan_code: "mail-seat",
    billing_provider: "local_psp",
  });
  const [domainName, setDomainName] = useState("");
  const [localPart, setLocalPart] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [quotaMb, setQuotaMb] = useState(0);
  const [checkoutUrl, setCheckoutUrl] = useState("");
  const [adminSessionToken, setAdminSessionToken] = useState("");
  const [notice, setNotice] = useState("");
  const [migrationRows, setMigrationRows] = useState<BulkMigrationRowState[]>([createBulkMigrationRow()]);
  const [migrationTestResults, setMigrationTestResults] = useState<BulkMigrationTestResult[]>([]);
  const [migrationImportText, setMigrationImportText] = useState("");
  const [migrationImportFileName, setMigrationImportFileName] = useState("");
  const [migrationActivity, setMigrationActivity] = useState<BulkMigrationActivity>({ mode: "idle", row_id: "", index: 0, total: 0 });
  const [migrationDragRowId, setMigrationDragRowId] = useState("");
  const [migrationDragOverRowId, setMigrationDragOverRowId] = useState("");
  const [migrationSelectedRowId, setMigrationSelectedRowId] = useState("");

  const appConfig = useQuery<AppConfig>({
    queryKey: ["app-config-admin"],
    queryFn: () => api.config(),
    staleTime: 5 * 60_000,
  });
  const providers = useQuery({
    queryKey: ["billing-providers"],
    queryFn: api.billingProviders,
    staleTime: 5 * 60_000,
  });
  const organizations = useQuery({
    queryKey: ["admin-organizations", adminKey],
    queryFn: () => api.adminOrganizations(adminKey),
    enabled: Boolean(adminKey.trim()),
    staleTime: 30_000,
  });
  const selectedOrg = useMemo(() => organizations.data?.organizations.find((org) => org.id === selectedOrgId) ?? null, [organizations.data?.organizations, selectedOrgId]);
  const domains = useQuery({
    queryKey: ["admin-domains", adminKey, selectedOrgId],
    queryFn: () => api.adminDomains(adminKey, selectedOrgId),
    enabled: Boolean(adminKey.trim() && selectedOrgId),
    staleTime: 30_000,
  });
  const mailboxes = useQuery({
    queryKey: ["admin-mailboxes", adminKey, selectedOrgId],
    queryFn: () => api.adminMailboxes(adminKey, selectedOrgId),
    enabled: Boolean(adminKey.trim() && selectedOrgId),
    staleTime: 30_000,
  });
  const billing = useQuery({
    queryKey: ["admin-billing", adminKey, selectedOrgId],
    queryFn: () => api.adminBilling(adminKey, selectedOrgId),
    enabled: Boolean(adminKey.trim() && selectedOrgId),
    staleTime: 15_000,
  });
  const provisioning = useQuery({
    queryKey: ["admin-provisioning", adminKey, selectedOrgId],
    queryFn: () => api.adminProvisioning(adminKey, selectedOrgId),
    enabled: Boolean(adminKey.trim() && selectedOrgId),
    staleTime: 15_000,
  });
  const migrations = useQuery({
    queryKey: ["admin-mail-migrations", adminKey, selectedOrgId],
    queryFn: () => api.adminMailMigrations(adminKey, selectedOrgId),
    enabled: Boolean(adminKey.trim() && selectedOrgId),
    refetchInterval: 5_000,
    staleTime: 5_000,
  });
  const providerItems = Array.isArray(providers.data?.providers) ? providers.data.providers : [];
  const organizationItems = Array.isArray(organizations.data?.organizations) ? organizations.data.organizations : [];
  const domainItems = Array.isArray(domains.data?.domains) ? domains.data.domains : [];
  const mailboxItems = Array.isArray(mailboxes.data?.mailboxes) ? mailboxes.data.mailboxes : [];
  const invoiceItems = Array.isArray(billing.data?.invoices) ? billing.data.invoices : [];
  const dnsItems = Array.isArray(provisioning.data?.dns_instructions) ? provisioning.data.dns_instructions : [];
  const migrationItems = Array.isArray(migrations.data?.jobs) ? migrations.data.jobs : [];

  useEffect(() => {
    if (!selectedOrgId && organizationItems[0]?.id) {
      setSelectedOrgId(organizationItems[0].id);
    }
  }, [organizationItems, selectedOrgId, setSelectedOrgId]);

  useEffect(() => {
    function handleShortcut(event: KeyboardEvent) {
      if (event.defaultPrevented) return;
      if (!(event.altKey && event.shiftKey && event.key.toLowerCase() === "c")) return;
      const row = migrationRows.find((item) => item.id === migrationSelectedRowId);
      if (!row) return;
      event.preventDefault();
      handleCopyMigrationRow(row.id);
      setNotice(`Copied ${row.mailbox_email.trim() || "selected"} row.`);
    }
    window.addEventListener("keydown", handleShortcut);
    return () => window.removeEventListener("keydown", handleShortcut);
  }, [migrationRows, migrationSelectedRowId]);

  const createOrganization = useMutation({
    mutationFn: (payload: CreateOrgForm) => api.adminCreateOrganization(adminKey, payload),
    onSuccess: async (result) => {
      setNotice(`Created ${result.organization.name}`);
      setSelectedOrgId(result.organization.id);
      setNewOrg({ name: "", primary_domain: "", timezone: DEFAULT_TIME_ZONE, plan_code: "mail-seat", billing_provider: "local_psp" });
      await queryClient.invalidateQueries({ queryKey: ["admin-organizations", adminKey] });
    }
  });
  const createDomain = useMutation({
    mutationFn: (payload: { domain_name: string }) => api.adminCreateDomain(adminKey, selectedOrgId, payload),
    onSuccess: async () => {
      setNotice("Domain created");
      setDomainName("");
      await queryClient.invalidateQueries({ queryKey: ["admin-domains", adminKey, selectedOrgId] });
      await queryClient.invalidateQueries({ queryKey: ["admin-organizations", adminKey] });
      await queryClient.invalidateQueries({ queryKey: ["admin-provisioning", adminKey, selectedOrgId] });
    }
  });
  const createMailbox = useMutation({
    mutationFn: (payload: { domain_id: string; local_part: string; display_name?: string; quota_mb?: number }) => api.adminCreateMailbox(adminKey, selectedOrgId, payload),
    onSuccess: async () => {
      setNotice("Mailbox created");
      setLocalPart("");
      setDisplayName("");
      setQuotaMb(0);
      await queryClient.invalidateQueries({ queryKey: ["admin-mailboxes", adminKey, selectedOrgId] });
      await queryClient.invalidateQueries({ queryKey: ["admin-organizations", adminKey] });
      await queryClient.invalidateQueries({ queryKey: ["admin-billing", adminKey, selectedOrgId] });
      await queryClient.invalidateQueries({ queryKey: ["admin-provisioning", adminKey, selectedOrgId] });
    }
  });
  const syncBilling = useMutation({
    mutationFn: () => api.adminBillingSync(adminKey, selectedOrgId),
    onSuccess: async () => {
      setNotice("Billing quantity synced");
      await queryClient.invalidateQueries({ queryKey: ["admin-billing", adminKey, selectedOrgId] });
    }
  });
  const createAdminToken = useMutation({
    mutationFn: () => api.adminSessionToken(adminKey, selectedOrgId),
    onSuccess: (data) => {
      setAdminSessionToken(data.admin_token);
      setNotice("Admin token created");
    }
  });
  const createCheckout = useMutation({
    mutationFn: () => api.adminBillingCheckout(adminKey, selectedOrgId, { success_url: window.location.origin, cancel_url: window.location.origin }),
    onSuccess: (data) => {
      const url = typeof data.checkout_url === "string" ? data.checkout_url : "";
      setCheckoutUrl(url);
      setNotice("Checkout session prepared");
    }
  });
  const runProvisioning = useMutation({
    mutationFn: () => api.adminRunProvisioning(adminKey, selectedOrgId),
    onSuccess: async () => {
      setNotice("Provisioning run completed");
      await queryClient.invalidateQueries({ queryKey: ["admin-provisioning", adminKey, selectedOrgId] });
      await queryClient.invalidateQueries({ queryKey: ["admin-billing", adminKey, selectedOrgId] });
      await queryClient.invalidateQueries({ queryKey: ["admin-organizations", adminKey] });
    }
  });
  const startBulkMigration = useMutation({
    mutationFn: (payload: { jobs: Array<{
      mailbox_email: string;
      mailbox_password: string;
      label?: string;
      source_host: string;
      source_port: number;
      source_security: "ssl" | "starttls" | "plain";
      source_skip_ssl_verify?: boolean;
      source_username: string;
      source_password: string;
      dry_run?: boolean;
      include_folders?: string[];
      exclude_folders?: string[];
    }> }) => api.adminStartBulkMailMigration(adminKey, selectedOrgId, payload),
    onSuccess: async (result) => {
      const created = result.jobs.length;
      const failed = result.errors.length;
      setNotice(`Started ${created} migration job${created === 1 ? "" : "s"}${failed ? `, ${failed} failed to queue` : ""}.`);
      setMigrationActivity({ mode: "idle", row_id: "", index: 0, total: 0 });
      await queryClient.invalidateQueries({ queryKey: ["admin-mail-migrations", adminKey, selectedOrgId] });
    },
    onError: () => {
      setMigrationActivity({ mode: "idle", row_id: "", index: 0, total: 0 });
    }
  });
  const testBulkMigration = useMutation({
    mutationFn: async (payload: { jobs: Array<{
      row_id: string;
      mailbox_email: string;
      mailbox_password: string;
      label?: string;
      source_host: string;
      source_port: number;
      source_security: "ssl" | "starttls" | "plain";
      source_skip_ssl_verify?: boolean;
      source_username: string;
      source_password: string;
      dry_run?: boolean;
      include_folders?: string[];
      exclude_folders?: string[];
    }> }) => {
      const results: BulkMigrationTestResult[] = [];
      for (const [index, job] of payload.jobs.entries()) {
        try {
          setMigrationActivity({ mode: "testing", row_id: job.row_id, index: index + 1, total: payload.jobs.length });
          const { row_id, ...requestPayload } = job;
          const result = await api.adminTestMailMigrationConnection(adminKey, selectedOrgId, requestPayload);
          results.push({ row_id, mailbox_email: job.mailbox_email, ok: result.ok, message: result.message });
        } catch (error) {
          results.push({ row_id: job.row_id, mailbox_email: job.mailbox_email, ok: false, message: error instanceof Error ? error.message : "Unable to test connection" });
        }
      }
      setMigrationActivity({ mode: "idle", row_id: "", index: 0, total: 0 });
      return results;
    },
    onSuccess: (results) => {
      setMigrationTestResults(results);
      const passed = results.filter((item) => item.ok).length;
      const failed = results.length - passed;
      setNotice(`Tested ${results.length} mailbox${results.length === 1 ? "" : "es"}: ${passed} passed, ${failed} failed.`);
    },
    onError: () => {
      setMigrationActivity({ mode: "idle", row_id: "", index: 0, total: 0 });
    }
  });

  const selectedProvider = providerItems.find((item: BillingProviderInfo) => item.provider === selectedOrg?.billing_provider);

  function signOut() {
    setAdminKey("");
    router.replace("/login");
  }

  function submitOrganization(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!adminKey.trim()) return;
    createOrganization.mutate(newOrg);
  }

  function buildBulkMigrationJob(row: BulkMigrationRowState, index: number): BulkMigrationJob | null {
    const mailbox_email = row.mailbox_email.trim();
    const mailbox_password = row.mailbox_password.trim();
    const source_host = row.source_host.trim();
    const source_username = row.source_username.trim();
    const source_password = row.source_password.trim();
    const source_port = Number.parseInt(row.source_port, 10) || 993;
    const label = row.label.trim();
    const include_folders = row.include_folders
      .split(",")
      .map((item) => item.trim())
      .filter(Boolean);
    const exclude_folders = row.exclude_folders
      .split(",")
      .map((item) => item.trim())
      .filter(Boolean);
    const hasAnyValue = [
      mailbox_email,
      mailbox_password,
      source_host,
      source_username,
      source_password,
      label,
      row.include_folders.trim(),
      row.exclude_folders.trim(),
      row.source_port.trim(),
    ].some(Boolean);
    if (!hasAnyValue) {
      return null;
    }
    if (!mailbox_email || !mailbox_password || !source_host || !source_username || !source_password) {
      throw new Error(`Row ${index + 1}: fill mailbox email, mailbox password, source host, source username, and source password.`);
    }
    if (!Number.isFinite(source_port) || source_port <= 0) {
      throw new Error(`Row ${index + 1}: source port must be a valid number.`);
    }
    return {
      row_id: row.id,
      mailbox_email,
      mailbox_password,
      label,
      source_host,
      source_port,
      source_security: row.source_security,
      source_skip_ssl_verify: row.source_skip_ssl_verify,
      source_username,
      source_password,
      dry_run: false,
      include_folders,
      exclude_folders,
    };
  }

  function buildBulkMigrationJobs() {
    const jobs = migrationRows.flatMap((row, index) => {
      const job = buildBulkMigrationJob(row, index + 1);
      return job ? [job] : [];
    });
    if (!jobs.length) {
      throw new Error("Add at least one migration row.");
    }
    return jobs;
  }

  function isBulkMigrationRowPopulated(row: BulkMigrationRowState) {
    return [
      row.mailbox_email.trim(),
      row.mailbox_password.trim(),
      row.source_host.trim(),
      row.source_username.trim(),
      row.source_password.trim(),
      row.label.trim(),
      row.include_folders.trim(),
      row.exclude_folders.trim(),
      row.source_port.trim(),
    ].some(Boolean);
  }

  function isBulkMigrationRowReady(row: BulkMigrationRowState) {
    return Boolean(
      row.mailbox_email.trim() &&
      row.mailbox_password.trim() &&
      row.source_host.trim() &&
      row.source_username.trim() &&
      row.source_password.trim()
    );
  }

  function parseCsvFields(line: string) {
    const fields: string[] = [];
    let current = "";
    let quoted = false;
    for (let index = 0; index < line.length; index += 1) {
      const char = line[index];
      const next = line[index + 1];
      if (quoted) {
        if (char === '"' && next === '"') {
          current += '"';
          index += 1;
        } else if (char === '"') {
          quoted = false;
        } else {
          current += char;
        }
        continue;
      }
      if (char === '"') {
        quoted = true;
        continue;
      }
      if (char === ",") {
        fields.push(current.trim());
        current = "";
        continue;
      }
      current += char;
    }
    fields.push(current.trim());
    return fields.map((field) => field.replace(/\r$/, ""));
  }

  function parseBulkMigrationImport(text: string) {
    return text
      .split(/\r?\n/)
      .map((line) => line.trim())
      .filter(Boolean)
      .map((line, index) => {
        if (/^mailbox_email\s*,/i.test(line) || /^mailbox_email\s*\|/i.test(line)) {
          return null;
        }
        const parts = line.includes("|") ? line.split("|").map((item) => item.trim()) : parseCsvFields(line);
        const isPipeFormat = line.includes("|");
        if (parts.length < 6) {
          throw new Error(`Line ${index + 1}: expected ${isPipeFormat ? "mailbox_email|mailbox_password|source_host|source_username|source_password|security" : "mailbox_email,mailbox_password,source_host,source_username,source_password,security"} with optional port, label, include_folders, exclude_folders`);
        }
        const [
          mailbox_email,
          mailbox_password,
          source_host,
          source_username,
          source_password,
          source_security,
          source_port = "993",
          label = "",
          include_folders = "",
          exclude_folders = BULK_MIGRATION_DEFAULT_EXCLUDES,
        ] = parts;
        const sourceSecurity = source_security.toLowerCase();
        if (!["ssl", "starttls", "plain"].includes(sourceSecurity)) {
          throw new Error(`Line ${index + 1}: security must be ssl, starttls, or plain.`);
        }
        return createBulkMigrationRow({
          mailbox_email,
          mailbox_password,
          source_host,
          source_username,
          source_password,
          source_security: sourceSecurity as BulkMigrationRowState["source_security"],
          source_port: Number(source_port) > 0 ? String(Number(source_port)) : "993",
          label,
          include_folders,
          exclude_folders,
        });
      })
      .filter(Boolean) as BulkMigrationRowState[];
  }

  function handleAppendImportedRows() {
    try {
      const imported = parseBulkMigrationImport(migrationImportText);
      if (!imported.length) {
        throw new Error("Paste at least one migration row.");
      }
      setMigrationRows((current) => {
        const next = current.filter((row) => isBulkMigrationRowPopulated(row));
        return [...next, ...imported];
      });
      setMigrationImportText("");
      setNotice(`Added ${imported.length} migration row${imported.length === 1 ? "" : "s"}.`);
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to import migration rows.");
    }
  }

  function handleReplaceImportedRows() {
    try {
      const imported = parseBulkMigrationImport(migrationImportText);
      if (!imported.length) {
        throw new Error("Paste at least one migration row.");
      }
      setMigrationRows(imported);
      setMigrationTestResults([]);
      setMigrationImportText("");
      setNotice(`Replaced with ${imported.length} migration row${imported.length === 1 ? "" : "s"}.`);
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to import migration rows.");
    }
  }

  async function handleMigrationImportFileChange(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file) return;
    try {
      const text = await file.text();
      setMigrationImportText(text);
      setMigrationImportFileName(file.name);
      setNotice(`Loaded ${file.name}.`);
    } catch {
      setNotice("Unable to read import file.");
    }
  }

  function handleAddMigrationRow() {
    setMigrationRows((current) => [...current, createBulkMigrationRow()]);
  }

  function handleCopyMigrationRow(rowId: string) {
    setMigrationRows((current) => {
      const source = current.find((row) => row.id === rowId);
      if (!source) return current;
      const duplicate = createBulkMigrationRow({
        mailbox_email: source.mailbox_email,
        mailbox_password: source.mailbox_password,
        label: source.label,
        source_host: source.source_host,
        source_port: source.source_port,
        source_security: source.source_security,
        source_skip_ssl_verify: source.source_skip_ssl_verify,
        source_username: source.source_username,
        source_password: source.source_password,
        include_folders: source.include_folders,
        exclude_folders: source.exclude_folders,
      });
      const index = current.findIndex((row) => row.id === rowId);
      const next = current.slice();
      next.splice(index + 1, 0, duplicate);
      return next;
    });
  }

  function moveMigrationRow(sourceRowId: string, targetRowId: string) {
    if (sourceRowId === targetRowId) return;
    setMigrationRows((current) => {
      const fromIndex = current.findIndex((row) => row.id === sourceRowId);
      const toIndex = current.findIndex((row) => row.id === targetRowId);
      if (fromIndex < 0 || toIndex < 0) return current;
      const next = current.slice();
      const [moved] = next.splice(fromIndex, 1);
      next.splice(fromIndex < toIndex ? toIndex - 1 : toIndex, 0, moved);
      return next;
    });
  }

  function handleMigrationDragStart(event: DragEvent<HTMLButtonElement>, rowId: string) {
    event.dataTransfer.effectAllowed = "move";
    setMigrationDragRowId(rowId);
  }

  function handleMigrationDragEnd() {
    setMigrationDragRowId("");
    setMigrationDragOverRowId("");
  }

  function handleMigrationDragOver(event: DragEvent<HTMLDivElement>, rowId: string) {
    if (!migrationDragRowId || migrationDragRowId === rowId) return;
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";
    setMigrationDragOverRowId(rowId);
  }

  function handleMigrationDrop(event: DragEvent<HTMLDivElement>, rowId: string) {
    event.preventDefault();
    if (!migrationDragRowId) return;
    moveMigrationRow(migrationDragRowId, rowId);
    handleMigrationDragEnd();
  }

  function handleRemoveMigrationRow(rowId: string) {
    setMigrationRows((current) => {
      if (current.length === 1) {
        return [createBulkMigrationRow()];
      }
      return current.filter((row) => row.id !== rowId);
    });
    setMigrationTestResults((current) => current.filter((result) => result.row_id !== rowId));
  }

  function updateMigrationRow(rowId: string, patch: Partial<BulkMigrationRowState>) {
    setMigrationRows((current) => current.map((row) => (row.id === rowId ? { ...row, ...patch } : row)));
  }

  function applyMigrationPreset(rowId: string, presetId: BulkMigrationPreset["id"]) {
    const preset = BULK_MIGRATION_PRESETS.find((item) => item.id === presetId);
    if (!preset) return;
    const patch: Partial<BulkMigrationRowState> = {
      source_security: preset.source_security,
    };
    if (preset.source_host) patch.source_host = preset.source_host;
    if (preset.source_port) patch.source_port = preset.source_port;
    if (typeof preset.include_folders === "string") patch.include_folders = preset.include_folders;
    if (typeof preset.exclude_folders === "string") patch.exclude_folders = preset.exclude_folders;
    updateMigrationRow(rowId, patch);
    setNotice(`Applied ${preset.label} preset.`);
  }

  function handleClearMigrationRows() {
    setMigrationRows([createBulkMigrationRow()]);
    setMigrationTestResults([]);
  }

  async function testMigrationRow(row: BulkMigrationRowState) {
    try {
      const job = buildBulkMigrationJob(row, migrationRows.findIndex((item) => item.id === row.id) + 1);
      if (!job) return;
      const { row_id: _rowId, ...requestPayload } = job;
      const result = await api.adminTestMailMigrationConnection(adminKey, selectedOrgId, requestPayload);
      setMigrationTestResults((current) => {
        const filtered = current.filter((item) => item.row_id !== row.id);
        return [...filtered, { row_id: row.id, mailbox_email: row.mailbox_email.trim(), ok: result.ok, message: result.message }];
      });
      setNotice(`${row.mailbox_email.trim()} test ${result.ok ? "passed" : "failed"}.`);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Unable to test connection";
      setMigrationTestResults((current) => {
        const filtered = current.filter((item) => item.row_id !== row.id);
        return [...filtered, { row_id: row.id, mailbox_email: row.mailbox_email.trim() || "Unnamed row", ok: false, message }];
      });
      setNotice(message);
    }
  }

  function handleTestBulkMigration() {
    try {
      const jobs = buildBulkMigrationJobs();
      void testBulkMigration.mutateAsync({ jobs });
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to parse migration rows.");
    }
  }

  function handleQueueBulkMigration() {
    try {
      const jobs = buildBulkMigrationJobs().map(({ row_id: _rowId, ...job }) => job);
      setMigrationActivity({ mode: "queueing", row_id: "", index: jobs.length ? 1 : 0, total: jobs.length });
      void startBulkMigration.mutate({ jobs });
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to parse migration rows.");
      setMigrationActivity({ mode: "idle", row_id: "", index: 0, total: 0 });
    }
  }

  return (
    <main className="min-h-screen bg-[radial-gradient(circle_at_top_left,rgba(240,253,244,0.95),rgba(255,255,255,0.96)_34%,rgba(239,246,255,0.98)_100%)] px-4 py-6 md:px-6 md:py-8">
      <div className="mx-auto grid max-w-7xl gap-6">
        <header className="grid gap-4 rounded-xl border border-slate-200/80 bg-white/90 p-6 shadow-soft md:grid-cols-[1fr_auto] md:items-center">
          <div>
            <BrandLogo subtitle="Admin console" />
            <h1 className="mt-4 text-3xl font-black text-slate-950">Platform admin</h1>
            <p className="mt-2 max-w-3xl text-sm leading-7 text-slate-600">
              Manage tenants, domains, mailboxes, and billing provider choice from one console.
            </p>
          </div>
          <div className="grid gap-3 rounded-xl border border-slate-200 bg-slate-50 p-4 transition hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white">
              <div className="flex items-center justify-between gap-3">
                <div className="grid gap-1">
                  <span className="text-xs font-black uppercase tracking-[0.16em] text-slate-500">Platform access</span>
                  <span className="text-sm font-semibold text-slate-600">Platform key active for this session</span>
                </div>
              <button type="button" onClick={signOut} className="theme-button-soft h-10 px-4 text-sm">
                Sign out
              </button>
            </div>
            <div className="flex flex-wrap gap-2">
              <button type="button" onClick={() => void organizations.refetch()} className="theme-button-soft h-10 px-4 text-sm">
                <RefreshCw size={16} />
                Load tenants
              </button>
              <button type="button" onClick={() => void syncBilling.mutate()} disabled={!selectedOrgId} className="theme-button h-10 px-4 text-sm disabled:opacity-50">
                <WalletCards size={16} />
                Sync billing
              </button>
            </div>
          </div>
        </header>

        {notice ? <div className="rounded-xl border border-[color-mix(in_srgb,var(--accent)_20%,white)] bg-[color-mix(in_srgb,var(--accent)_8%,white)] px-4 py-3 text-sm font-semibold text-[var(--accent)]">{notice}</div> : null}
        <InstallSetupPanel config={appConfig.data} />

        <section className="grid gap-6 xl:grid-cols-[360px_minmax(0,1fr)]">
          <div className="grid gap-6">
            <div className="rounded-xl border border-slate-200/80 bg-white p-5 shadow-soft">
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-500">Providers</p>
                  <h2 className="text-xl font-black text-slate-950">Billing provider layer</h2>
                </div>
                <Layers3 className="text-slate-400" />
              </div>
              <div className="mt-4 grid gap-3">
                {providerItems.map((provider) => (
                  <div
                    key={provider.provider}
                    className={clsx(
                      "rounded-xl border p-4 transition",
                      selectedOrg?.billing_provider === provider.provider
                        ? "border-[color-mix(in_srgb,var(--accent)_20%,white)] bg-[color-mix(in_srgb,var(--accent)_8%,white)]"
                        : "border-slate-200 bg-slate-50 hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white"
                    )}
                  >
                    <div className="flex items-center justify-between gap-2">
                      <strong className="text-sm font-black text-slate-950">{provider.provider}</strong>
                      <span className="rounded-full bg-white px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-slate-500">{selectedOrg?.billing_provider === provider.provider ? "Selected" : provider.capabilities.local_methods ? "Local" : "Card"}</span>
                    </div>
                    <div className="mt-2 grid grid-cols-2 gap-2 text-xs font-semibold text-slate-600">
                      <span>Recurring: {provider.capabilities.recurring ? "Yes" : "No"}</span>
                      <span>Admin: {provider.capabilities.customer_admin ? "Yes" : "No"}</span>
                      <span>Invoices: {provider.capabilities.invoices ? "Yes" : "No"}</span>
                      <span>Webhooks: {provider.capabilities.webhooks ? "Yes" : "No"}</span>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            <form onSubmit={submitOrganization} className="rounded-xl border border-slate-200/80 bg-white p-5 shadow-soft">
              <div className="flex items-center gap-3">
                <Building2 className="text-slate-400" />
                <div>
                  <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-500">Create tenant</p>
                  <h2 className="text-xl font-black text-slate-950">New organization</h2>
                </div>
              </div>
              <div className="mt-4 grid gap-3">
                <input value={newOrg.name} onChange={(event) => setNewOrg((current) => ({ ...current, name: event.target.value }))} className="field h-11" placeholder="Organization name" />
                <input value={newOrg.primary_domain} onChange={(event) => setNewOrg((current) => ({ ...current, primary_domain: event.target.value }))} className="field h-11" placeholder="Primary domain" />
                <select value={newOrg.billing_provider} onChange={(event) => setNewOrg((current) => ({ ...current, billing_provider: event.target.value }))} className="field h-11">
                  <option value="local_psp">Local PSP (Thailand)</option>
                  <option value="stripe">Stripe</option>
                </select>
                <button className="theme-button h-11 px-4 text-sm disabled:opacity-60" disabled={createOrganization.isPending || !adminKey.trim() || !newOrg.name.trim()}>
                  {createOrganization.isPending ? "Creating..." : "Create organization"}
                </button>
              </div>
            </form>

            <div className="rounded-xl border border-slate-200/80 bg-white p-5 shadow-soft">
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-500">Organizations</p>
                  <h2 className="text-xl font-black text-slate-950">Tenant list</h2>
                </div>
                <Users className="text-slate-400" />
              </div>
              <div className="mt-4 grid gap-2">
                {organizationItems.map((org) => (
                  <button key={org.id} type="button" onClick={() => setSelectedOrgId(org.id)} className={clsx("rounded-xl border px-4 py-3 text-left transition", selectedOrgId === org.id ? "border-[color-mix(in_srgb,var(--accent)_18%,white)] bg-[color-mix(in_srgb,var(--accent)_8%,white)]" : "border-slate-200 bg-slate-50 hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white")}>
                    <div className="flex items-center justify-between gap-2">
                      <strong className="text-sm font-black text-slate-950">{org.name}</strong>
                      <span className="rounded-full bg-white px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-slate-500">{org.billing_provider}</span>
                    </div>
                    <p className="mt-1 text-xs font-semibold text-slate-500">{org.primary_domain || "No primary domain"}</p>
                    <p className="mt-1 text-xs font-semibold text-slate-500">{org.seat_quantity} active seats · {org.status}</p>
                  </button>
                ))}
              </div>
            </div>
          </div>

          <div className="grid gap-6">
            <div className="grid gap-4 rounded-xl border border-slate-200/80 bg-white p-6 shadow-soft">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-500">Selected tenant</p>
                  <h2 className="text-2xl font-black text-slate-950">{selectedOrg?.name || "Choose a tenant"}</h2>
                </div>
                {selectedOrg ? (
                  <div className="flex gap-2">
                    <button type="button" onClick={() => void createAdminToken.mutate()} className="theme-button-soft h-10 px-4 text-sm">Create admin token</button>
                    <button type="button" onClick={() => void createCheckout.mutate()} className="theme-button h-10 px-4 text-sm">Create checkout</button>
                    <button type="button" onClick={() => void runProvisioning.mutate()} className="theme-button-soft h-10 px-4 text-sm">Run provisioning</button>
                  </div>
                ) : null}
              </div>

              {selectedOrg ? (
                <>
                  <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
                    <StatCard label="Billing provider" value={selectedOrg.billing_provider} />
                    <StatCard label="Active seats" value={String(selectedOrg.seat_quantity)} />
                    <StatCard label="Status" value={selectedOrg.status} />
                    <StatCard label="Mailbox limit" value={String(selectedOrg.mailbox_limit || 0)} />
                  </div>
                  <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600 transition hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white">
                    <p className="font-black text-slate-900">Provider capability</p>
                    <p className="mt-1">{selectedProvider ? `${selectedProvider.provider}: ${selectedProvider.capabilities.local_methods ? "local methods enabled" : "card-only"}` : "Loading provider info"}</p>
                    {checkoutUrl ? <p className="mt-2 break-all font-semibold text-emerald-700">Checkout reference: {checkoutUrl}</p> : null}
                    {adminSessionToken ? <p className="mt-1 break-all font-semibold text-slate-700">Admin token: {adminSessionToken}</p> : null}
                  </div>
                  <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600 transition hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white">
                    <p className="font-black text-slate-900">Provisioning state</p>
                    <div className="mt-2 grid gap-2 sm:grid-cols-3">
                      <MiniCard title="Org status" value={provisioning.data?.organization_status || selectedOrg.status} />
                      <MiniCard title="Subscription" value={provisioning.data?.subscription_status || billing.data?.subscription?.status || "loading"} />
                      <MiniCard title="Events" value={String(Array.isArray(provisioning.data?.provisioning_events) ? provisioning.data.provisioning_events.length : 0)} />
                    </div>
                    {dnsItems.length ? (
                      <div className="mt-3 grid gap-2">
                        {dnsItems.slice(0, 3).map((item) => (
                          <div key={`${item.host}-${item.type}-${item.value}`} className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-600">
                            <span className="font-black text-slate-900">{item.host}</span> {item.type} {item.value}
                          </div>
                        ))}
                      </div>
                    ) : null}
                  </div>
                  <div className="grid gap-3 md:grid-cols-2">
                    <form onSubmit={(event) => {
                      event.preventDefault();
                      if (!domainName.trim()) return;
                      createDomain.mutate({ domain_name: domainName.trim() });
                    }} className="rounded-xl border border-slate-200 bg-white p-4">
                      <p className="text-sm font-black text-slate-900">Add domain</p>
                      <div className="mt-3 flex gap-2">
                        <input value={domainName} onChange={(event) => setDomainName(event.target.value)} className="field h-11 flex-1" placeholder="tenant.co.th" />
                        <button className="theme-button h-11 px-4 text-sm disabled:opacity-60" disabled={createDomain.isPending || !domainName.trim()}>Add</button>
                      </div>
                    </form>
                    <form onSubmit={(event) => {
                      event.preventDefault();
                      const targetDomain = domains.data?.domains[0];
                    if (!targetDomain || !localPart.trim()) return;
                      createMailbox.mutate({ domain_id: targetDomain.id, local_part: localPart.trim(), display_name: displayName.trim(), quota_mb: quotaMb });
                    }} className="rounded-xl border border-slate-200 bg-white p-4">
                      <p className="text-sm font-black text-slate-900">Add mailbox</p>
                      <div className="mt-3 grid gap-2">
                        <input value={localPart} onChange={(event) => setLocalPart(event.target.value)} className="field h-11" placeholder="sales" />
                        <input value={displayName} onChange={(event) => setDisplayName(event.target.value)} className="field h-11" placeholder="Display name" />
                        <input value={quotaMb} onChange={(event) => setQuotaMb(Number(event.target.value || 0))} className="field h-11" type="number" min={0} placeholder="Quota MB" />
                        <button className="theme-button h-11 px-4 text-sm disabled:opacity-60" disabled={createMailbox.isPending || !domainItems.length || !localPart.trim()}>Add mailbox</button>
                      </div>
                    </form>
                  </div>
                </>
              ) : null}
            </div>

            <div className="grid gap-6">
              <Panel title="Mailboxes" icon={<Users className="text-slate-400" />}>
                <ListData items={mailboxItems} emptyText="No mailboxes yet." renderItem={(mailbox: Mailbox) => (
                  <div className="rounded-xl border border-slate-200 bg-white p-4">
                    <div className="flex items-center justify-between">
                      <strong className="text-sm font-black text-slate-950">{mailbox.email}</strong>
                      <span className="rounded-full bg-slate-100 px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-slate-500">{mailbox.status}</span>
                    </div>
                    <p className="mt-2 text-xs font-semibold text-slate-500">{mailbox.display_name || "No display name"} · {mailbox.quota_mb} MB</p>
                  </div>
                )} />
              </Panel>
            </div>

            <Panel title="Billing" icon={<WalletCards className="text-slate-400" />}>
              <div className="grid gap-4">
                <div className="grid gap-2 sm:grid-cols-3">
                  <MiniCard title="Subscription" value={billing.data?.subscription?.status || "loading"} />
                  <MiniCard title="Quantity" value={String(billing.data?.subscription?.quantity || 0)} />
                  <MiniCard title="Invoices" value={String(billing.data?.invoices?.length || 0)} />
                </div>
                <ListData items={invoiceItems as InvoiceRecord[]} emptyText="No invoices yet." renderItem={(invoice: InvoiceRecord) => (
                    <div className="rounded-xl border border-slate-200 bg-white p-4">
                    <div className="flex items-center justify-between">
                      <strong className="text-sm font-black text-slate-950">{invoice.provider_invoice_id || invoice.id}</strong>
                      <span className="rounded-full bg-slate-100 px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-slate-500">{invoice.status}</span>
                    </div>
                    <p className="mt-2 text-xs font-semibold text-slate-500">{invoice.amount_due} {invoice.currency}</p>
                  </div>
                )} />
              </div>
            </Panel>

            <Panel title="Provisioning" icon={<Shield className="text-slate-400" />}>
              <div className="grid gap-4">
                <div className="grid gap-2 sm:grid-cols-3">
                  <MiniCard title="Organization" value={provisioning.data?.organization_status || "loading"} />
                  <MiniCard title="Subscription" value={provisioning.data?.subscription_status || "loading"} />
                  <MiniCard title="Actions" value={String(provisioning.data?.actions?.length || 0)} />
                </div>
                <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600">
                  <p className="font-black text-slate-900">Onboarding email</p>
                  <p className="mt-1 text-xs font-semibold text-slate-500">{provisioning.data?.onboarding_email_subject || "No onboarding email yet."}</p>
                  {provisioning.data?.onboarding_email_body ? <pre className="mt-3 max-h-64 overflow-auto whitespace-pre-wrap rounded-lg border border-slate-200 bg-white p-3 text-xs leading-6 text-slate-600">{provisioning.data.onboarding_email_body}</pre> : null}
                </div>
              </div>
            </Panel>

            <Panel title="Mail Migration" icon={<RefreshCw className="text-slate-400" />}>
              <div className="grid gap-4">
                <div className="rounded-xl border border-slate-200 bg-slate-50 p-4">
                  <div className="flex flex-wrap items-start justify-between gap-3">
                    <div>
                      <p className="text-sm font-black text-slate-900">Bulk queue</p>
                      <p className="mt-1 max-w-2xl text-xs font-semibold leading-6 text-slate-500">
                        Add one row per mailbox. Fill destination mailbox credentials and the source IMAP account, or paste multiple rows below from a spreadsheet.
                      </p>
                    </div>
                    <div className="flex flex-wrap gap-2">
                      <button type="button" onClick={handleAddMigrationRow} className="theme-button-soft h-10 px-4 text-sm">
                        Add row
                      </button>
                      <button type="button" onClick={handleClearMigrationRows} className="theme-button-soft h-10 px-4 text-sm">
                        Clear all
                      </button>
                    </div>
                  </div>
                  <div className="mt-4 grid gap-3 rounded-xl border border-dashed border-slate-200 bg-white p-4">
                    <div className="flex flex-wrap items-center justify-between gap-2">
                      <div>
                        <p className="text-sm font-black text-slate-900">Paste import</p>
                        <p className="mt-1 text-xs font-semibold leading-6 text-slate-500">
                          One line per mailbox. Use pipe format or comma-separated CSV with quoted values for folders that contain commas.
                        </p>
                      </div>
                      <span className="rounded-full bg-slate-100 px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-slate-500">
                        Rows stay editable
                      </span>
                    </div>
                    <div className="rounded-xl border border-slate-200 bg-slate-50 p-3">
                      <div className="flex flex-wrap items-center justify-between gap-3">
                        <div className="grid gap-1">
                          <p className="text-xs font-black uppercase tracking-[0.12em] text-slate-500">Import from file</p>
                          <p className="text-xs font-semibold text-slate-500">Choose a `.txt` or `.csv` file using pipe rows or comma-separated CSV.</p>
                        </div>
                        <label className="theme-button-soft inline-flex h-10 cursor-pointer items-center px-4 text-sm">
                          Choose file
                          <input
                            type="file"
                            accept=".txt,.csv,text/plain,text/csv"
                            onChange={handleMigrationImportFileChange}
                            className="hidden"
                          />
                        </label>
                      </div>
                      <div className="mt-3 flex flex-wrap items-center justify-between gap-2">
                        <p className="text-xs font-semibold text-slate-500">
                          {migrationImportFileName ? `Loaded file: ${migrationImportFileName}` : "No file selected."}
                        </p>
                        <button
                          type="button"
                          onClick={() => {
                            setMigrationImportText("");
                            setMigrationImportFileName("");
                          }}
                          className="theme-button-soft h-9 px-3 text-[11px]"
                        >
                          Clear file
                        </button>
                      </div>
                    </div>
                    <textarea
                      value={migrationImportText}
                      onChange={(event) => setMigrationImportText(event.target.value)}
                      className="field min-h-28 w-full p-3 font-mono text-xs leading-6"
                      placeholder="sales@tenant.com|dest-pass|imap.oldhost.com|sales@oldhost.com|source-pass|ssl|993|Cutover 1|Inbox,Sent|Trash,Junk,Spam"
                    />
                    <div className="flex flex-wrap gap-2">
                      <button type="button" onClick={handleAppendImportedRows} className="theme-button-soft h-10 px-4 text-sm">
                        Append rows
                      </button>
                      <button type="button" onClick={handleReplaceImportedRows} className="theme-button h-10 px-4 text-sm">
                        Replace rows
                      </button>
                      <button type="button" onClick={() => setMigrationImportText("")} className="theme-button-soft h-10 px-4 text-sm">
                        Clear paste
                      </button>
                    </div>
                  </div>
                  <div className="mt-4 grid gap-2 sm:grid-cols-3">
                    <MiniCard title="Rows" value={String(migrationRows.length)} />
                    <MiniCard title="Ready" value={String(migrationRows.filter(isBulkMigrationRowReady).length)} />
                    <MiniCard title="Tested" value={String(migrationTestResults.length)} />
                  </div>
                  <div className="mt-4 grid gap-2 md:grid-cols-2">
                    <button
                      type="button"
                      onClick={handleTestBulkMigration}
                      disabled={!selectedOrgId || testBulkMigration.isPending}
                      className="theme-button-soft h-10 px-4 text-sm disabled:opacity-50"
                    >
                      {testBulkMigration.isPending ? "Testing..." : "Test all rows"}
                    </button>
                    <button
                      type="button"
                      onClick={handleQueueBulkMigration}
                      disabled={!selectedOrgId || startBulkMigration.isPending}
                      className="theme-button h-10 px-4 text-sm disabled:opacity-50"
                    >
                      {startBulkMigration.isPending ? "Queueing..." : "Queue bulk migrations"}
                    </button>
                  </div>
                  {migrationActivity.mode !== "idle" ? (
                    <div className="mt-4 rounded-xl border border-[color-mix(in_srgb,var(--accent)_18%,white)] bg-[color-mix(in_srgb,var(--accent)_8%,white)] px-4 py-3 text-sm font-semibold text-slate-700">
                      {migrationActivity.mode === "testing"
                        ? `Testing row ${migrationActivity.index} of ${migrationActivity.total}`
                        : `Queueing ${migrationActivity.total} migration job${migrationActivity.total === 1 ? "" : "s"}`
                      }
                    </div>
                  ) : null}
                  <div className="mt-4 grid gap-3">
                    {migrationRows.map((row, index) => {
                      const result = migrationTestResults.find((item) => item.row_id === row.id);
                      const populated = isBulkMigrationRowPopulated(row);
                      const ready = isBulkMigrationRowReady(row);
                      const rowBusy = migrationActivity.row_id === row.id;
                      return (
                        <div
                          key={row.id}
                          onMouseDown={() => setMigrationSelectedRowId(row.id)}
                          onFocusCapture={() => setMigrationSelectedRowId(row.id)}
                          onDragOver={(event) => handleMigrationDragOver(event, row.id)}
                          onDrop={(event) => handleMigrationDrop(event, row.id)}
                          className={clsx(
                            "rounded-xl border bg-white p-4 shadow-sm transition",
                            migrationSelectedRowId === row.id ? "ring-2 ring-[color-mix(in_srgb,var(--accent)_16%,white)]" : "",
                            migrationDragOverRowId === row.id && migrationDragRowId !== row.id
                              ? "border-[color-mix(in_srgb,var(--accent)_24%,white)] bg-[color-mix(in_srgb,var(--accent)_6%,white)]"
                              : "border-slate-200"
                          )}
                        >
                          <div className="flex flex-wrap items-center justify-between gap-3">
                            <div className="flex items-center gap-3">
                              <button
                                type="button"
                                draggable
                                onDragStart={(event) => handleMigrationDragStart(event, row.id)}
                                onDragEnd={handleMigrationDragEnd}
                                className="flex h-8 w-8 cursor-grab items-center justify-center rounded-full bg-[color-mix(in_srgb,var(--accent)_12%,white)] text-[var(--accent)] transition active:cursor-grabbing"
                                aria-label={`Drag row ${index + 1}`}
                                title="Drag to reorder"
                              >
                                <GripVertical size={16} />
                              </button>
                              <div>
                                <p className="text-[10px] font-black uppercase tracking-[0.12em] text-slate-400">Row {index + 1}</p>
                                <p className="text-sm font-black text-slate-950">{row.mailbox_email.trim() || "New migration row"}</p>
                                <p className="text-xs font-semibold text-slate-500">
                                  {ready ? "Ready to test and queue" : populated ? "Incomplete row" : "Empty row"}
                                </p>
                              </div>
                            </div>
                            <div className="flex flex-wrap gap-2">
                              {migrationSelectedRowId === row.id ? (
                                <span className="rounded-full bg-[color-mix(in_srgb,var(--accent)_12%,white)] px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-[var(--accent)]">
                                  Selected
                                </span>
                              ) : null}
                              {rowBusy ? (
                                <span className="rounded-full bg-[color-mix(in_srgb,var(--accent)_12%,white)] px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-[var(--accent)]">
                                  {migrationActivity.mode === "testing" ? "Testing" : "Queueing"}
                                </span>
                              ) : null}
                              {BULK_MIGRATION_PRESETS.map((preset) => (
                                <button
                                  key={preset.id}
                                  type="button"
                                  onClick={() => applyMigrationPreset(row.id, preset.id)}
                                  className="theme-button-soft h-9 px-3 text-[11px]"
                                  title={preset.description}
                                >
                                  {preset.label}
                                </button>
                              ))}
                              {result ? (
                                <span className={clsx("rounded-full px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em]", result.ok ? "bg-emerald-100 text-emerald-700" : "bg-red-100 text-red-700")}>
                                  {result.ok ? "Passed" : "Failed"}
                                </span>
                              ) : null}
                              <button
                                type="button"
                                onClick={() => void testMigrationRow(row)}
                                disabled={!selectedOrgId || !ready || testBulkMigration.isPending || migrationActivity.mode === "queueing"}
                                className="theme-button-soft h-9 px-3 text-[11px] disabled:opacity-50"
                              >
                                {rowBusy && migrationActivity.mode === "testing" ? "Testing..." : "Test row"}
                              </button>
                              <button type="button" onClick={() => handleCopyMigrationRow(row.id)} className="theme-button-soft h-9 px-3 text-[11px]">
                                Copy
                              </button>
                              <button type="button" onClick={() => handleRemoveMigrationRow(row.id)} className="theme-button-soft h-9 px-3 text-[11px]">
                                Delete
                              </button>
                            </div>
                          </div>
                          <div className="mt-4 grid gap-3 lg:grid-cols-2 xl:grid-cols-3">
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Mailbox email
                              <input
                                value={row.mailbox_email}
                                onChange={(event) => updateMigrationRow(row.id, { mailbox_email: event.target.value })}
                                className="field h-11 normal-case tracking-normal"
                                placeholder="sales@tenant.com"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Mailbox password
                              <input
                                value={row.mailbox_password}
                                onChange={(event) => updateMigrationRow(row.id, { mailbox_password: event.target.value })}
                                className="field h-11"
                                type="password"
                                placeholder="Destination mailbox password"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Label
                              <input
                                value={row.label}
                                onChange={(event) => updateMigrationRow(row.id, { label: event.target.value })}
                                className="field h-11"
                                placeholder="Cutover / tenant note"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Source host
                              <input
                                value={row.source_host}
                                onChange={(event) => updateMigrationRow(row.id, { source_host: event.target.value })}
                                className="field h-11"
                                placeholder="imap.oldhost.com"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Source username
                              <input
                                value={row.source_username}
                                onChange={(event) => updateMigrationRow(row.id, { source_username: event.target.value })}
                                className="field h-11"
                                placeholder="user@oldhost.com"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Source password
                              <input
                                value={row.source_password}
                                onChange={(event) => updateMigrationRow(row.id, { source_password: event.target.value })}
                                className="field h-11"
                                type="password"
                                placeholder="Source mailbox password"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Source port
                              <input
                                value={row.source_port}
                                onChange={(event) => updateMigrationRow(row.id, { source_port: event.target.value })}
                                className="field h-11"
                                inputMode="numeric"
                                placeholder="993"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Security
                              <select
                                value={row.source_security}
                                onChange={(event) => updateMigrationRow(row.id, { source_security: event.target.value as BulkMigrationRowState["source_security"] })}
                                className="field h-11"
                              >
                                <option value="ssl">SSL</option>
                                <option value="starttls">STARTTLS</option>
                                <option value="plain">Plain</option>
                              </select>
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Include folders
                              <input
                                value={row.include_folders}
                                onChange={(event) => updateMigrationRow(row.id, { include_folders: event.target.value })}
                                className="field h-11"
                                placeholder="Inbox,Sent"
                              />
                            </label>
                            <label className="grid gap-1 text-xs font-black uppercase tracking-[0.12em] text-slate-500">
                              Exclude folders
                              <input
                                value={row.exclude_folders}
                                onChange={(event) => updateMigrationRow(row.id, { exclude_folders: event.target.value })}
                                className="field h-11"
                                placeholder="Trash,Junk,Spam"
                              />
                            </label>
                          </div>
                          <div className="mt-3 flex flex-wrap items-center justify-between gap-2 border-t border-slate-200 pt-3">
                            <p className="text-xs font-semibold text-slate-500">
                              {ready ? "Row ready to queue." : populated ? "Fill all source and destination fields before testing." : "Blank rows are ignored until they contain values."}
                            </p>
                            {result ? (
                              <p className={clsx("text-xs font-semibold", result.ok ? "text-emerald-700" : "text-red-600")}>{result.message}</p>
                            ) : null}
                          </div>
                        </div>
                      );
                    })}
                  </div>
                  {migrationTestResults.length ? (
                    <div className="mt-4 grid gap-2">
                      {migrationTestResults.map((result) => (
                        <div key={result.row_id} className={clsx("rounded-lg border px-3 py-2 text-xs font-semibold", result.ok ? "border-emerald-200 bg-emerald-50 text-emerald-800" : "border-red-200 bg-red-50 text-red-700")}>
                          <div className="flex flex-wrap items-center justify-between gap-2">
                            <strong className="text-sm font-black">{result.mailbox_email}</strong>
                            <span>{result.ok ? "Passed" : "Failed"}</span>
                          </div>
                          <p className="mt-1 leading-5">{result.message}</p>
                        </div>
                      ))}
                    </div>
                  ) : null}
                </div>
                <div className="flex items-center justify-between gap-3">
                  <p className="text-sm text-slate-600">Mailbox migration jobs across this tenant.</p>
                  <button type="button" onClick={() => void migrations.refetch()} className="theme-button-soft h-10 px-4 text-sm">
                    <RefreshCw size={16} className={clsx(migrations.isFetching && "animate-spin")} />
                    Refresh
                  </button>
                </div>
                <ListData items={migrationItems as MailMigrationJob[]} emptyText="No migration jobs yet." renderItem={(job: MailMigrationJob) => (
                  <div className="rounded-xl border border-slate-200 bg-white p-4">
                    <div className="flex flex-wrap items-start justify-between gap-2">
                      <div>
                        <div className="flex flex-wrap items-center gap-2">
                          <span className="rounded-full bg-[color-mix(in_srgb,var(--accent)_10%,white)] px-2 py-1 text-[10px] font-black uppercase tracking-[0.12em] text-[var(--accent)]">{job.status}</span>
                          <span className="text-[11px] font-semibold text-slate-400">{job.id}</span>
                        </div>
                        <p className="mt-2 text-sm font-black text-slate-950">{job.mailbox_email}</p>
                        <p className="mt-1 text-xs font-semibold text-slate-500">{job.source_username} via {job.source_host}:{job.source_port}</p>
                        <p className="mt-1 text-xs font-semibold text-slate-500">Phase: {job.phase} · processed {job.processed_messages} · copied {job.copied_messages} · failed {job.failed_messages}</p>
                      </div>
                    </div>
                    {job.last_error ? <p className="mt-3 text-xs font-bold text-red-600">{job.last_error}</p> : null}
                    {job.log_excerpt ? <pre className="mt-3 min-h-[16rem] max-h-[32rem] overflow-auto whitespace-pre-wrap rounded-lg border border-slate-200 bg-slate-950 p-4 font-mono text-xs leading-6 text-slate-100">{job.log_excerpt}</pre> : null}
                  </div>
                )} />
              </div>
            </Panel>
          </div>
        </section>
      </div>
    </main>
  );
}

function Panel({ title, icon, children }: { title: string; icon: React.ReactNode; children: React.ReactNode }) {
  return (
    <section className="rounded-xl border border-slate-200/80 bg-white p-5 shadow-soft">
      <div className="flex items-center gap-3">
        {icon}
        <h3 className="text-xl font-black text-slate-950">{title}</h3>
      </div>
      <div className="mt-4">{children}</div>
    </section>
  );
}

function ListData<T>({ items, emptyText, renderItem }: { items: T[]; emptyText: string; renderItem: (item: T) => React.ReactNode }) {
  if (!items.length) return <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50 p-4 text-sm font-semibold text-slate-500">{emptyText}</div>;
  return <div className="grid gap-3">{items.map((item, index) => <div key={index}>{renderItem(item)}</div>)}</div>;
}

function StatCard({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 transition hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white">
      <p className="text-xs font-black uppercase tracking-[0.14em] text-slate-500">{label}</p>
      <p className="mt-2 text-lg font-black text-slate-950">{value}</p>
    </div>
  );
}

function MiniCard({ title, value }: { title: string; value: string }) {
  return (
    <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 transition hover:border-[color-mix(in_srgb,var(--accent)_18%,white)] hover:bg-white">
      <p className="text-xs font-black uppercase tracking-[0.14em] text-slate-500">{title}</p>
      <p className="mt-2 text-base font-black text-slate-950">{value}</p>
    </div>
  );
}
