import { useEffect, useMemo, useState } from "react";
import { Pencil, Plus, Search, Trash2 } from "lucide-react";
import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
import { createTenant, fetchSystemSettings, fetchTenantOwnerCandidates, fetchTenants, updateTenant, type SystemSettingsItem, type TenantAdminItem, type TenantOwnerCandidate } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
import { Dialog } from "@govoplan/core-webui";
import { FormField } from "@govoplan/core-webui";
import { StatusBadge } from "@govoplan/core-webui";
import { ConfirmDialog } from "@govoplan/core-webui";
import { AdminIconButton, AdminPageLayout, adminErrorMessage, formatAdminDateTime as formatDateTime } from "@govoplan/core-webui";

type OverrideValue = "inherit" | "allow" | "deny";
type TenantDraft = {
  slug: string;
  name: string;
  ownerAccountId: string;
  description: string;
  defaultLocale: string;
  isActive: boolean;
  customGroups: OverrideValue;
  customRoles: OverrideValue;
  apiKeys: OverrideValue;
};

const emptyDraft: TenantDraft = {
  slug: "",
  name: "",
  ownerAccountId: "",
  description: "",
  defaultLocale: "en",
  isActive: true,
  customGroups: "inherit",
  customRoles: "inherit",
  apiKeys: "inherit"
};

function fromOverride(value?: boolean | null): OverrideValue {
  if (value === true) return "allow";
  if (value === false) return "deny";
  return "inherit";
}

function toOverride(value: OverrideValue): boolean | null {
  if (value === "allow") return true;
  if (value === "deny") return false;
  return null;
}

export default function TenantsPanel({
  settings,
  auth,
  canCreate,
  canUpdate,
  canSuspend,
  onAuthRefresh
}: {
  settings: ApiSettings;
  auth: AuthInfo;
  canCreate: boolean;
  canUpdate: boolean;
  canSuspend: boolean;
  onAuthRefresh: () => Promise<void>;
}) {
  const [tenants, setTenants] = useState<TenantAdminItem[]>([]);
  const [systemSettings, setSystemSettings] = useState<SystemSettingsItem | null>(null);
  const [ownerCandidates, setOwnerCandidates] = useState<TenantOwnerCandidate[]>([]);
  const [editing, setEditing] = useState<TenantAdminItem | "new" | null>(null);
  const [viewing, setViewing] = useState<TenantAdminItem | null>(null);
  const [draft, setDraft] = useState<TenantDraft>(emptyDraft);
  const [confirmSuspend, setConfirmSuspend] = useState<TenantAdminItem | null>(null);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [success, setSuccess] = useState("");

  async function load() {
    setLoading(true);
    setError("");
    try {
      const [nextTenants, nextOwnerCandidates, nextSystemSettings] = await Promise.all([
        fetchTenants(settings),
        canCreate ? fetchTenantOwnerCandidates(settings) : Promise.resolve([]),
        fetchSystemSettings(settings).catch(() => null)
      ]);
      setTenants(nextTenants);
      setOwnerCandidates(nextOwnerCandidates);
      setSystemSettings(nextSystemSettings);
    } catch (err) {
      setError(adminErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => { void load(); }, [settings.accessToken, settings.apiBaseUrl]);

  function openCreate() {
    setDraft({ ...emptyDraft, ownerAccountId: auth.user.account_id });
    setEditing("new");
    setError("");
  }

  function openEdit(tenant: TenantAdminItem) {
    setDraft({
      slug: tenant.slug,
      name: tenant.name,
      ownerAccountId: "",
      description: tenant.description || "",
      defaultLocale: tenant.default_locale || "en",
      isActive: tenant.is_active,
      customGroups: fromOverride(tenant.allow_custom_groups),
      customRoles: fromOverride(tenant.allow_custom_roles),
      apiKeys: fromOverride(tenant.allow_api_keys)
    });
    setEditing(tenant);
    setError("");
  }

  async function save() {
    setBusy(true);
    setError("");
    try {
      const governance = {
        allow_custom_groups: toOverride(draft.customGroups),
        allow_custom_roles: toOverride(draft.customRoles),
        allow_api_keys: toOverride(draft.apiKeys)
      };
      if (editing === "new") {
        const created = await createTenant(settings, {
          slug: draft.slug,
          name: draft.name,
          owner_account_id: draft.ownerAccountId || null,
          description: draft.description || null,
          default_locale: draft.defaultLocale,
          settings: {},
          ...governance
        });
        const selectedOwner = ownerCandidates.find((candidate) => candidate.account_id === draft.ownerAccountId);
        setSuccess(`Tenant ${created.name} created with ${selectedOwner?.display_name || selectedOwner?.email || "the selected account"} as Owner.`);
        await onAuthRefresh();
      } else if (editing) {
        const payload: Parameters<typeof updateTenant>[2] = {};
        if (canUpdate) {
          payload.name = draft.name;
          payload.description = draft.description || null;
          payload.default_locale = draft.defaultLocale;
          payload.allow_custom_groups = governance.allow_custom_groups;
          payload.allow_custom_roles = governance.allow_custom_roles;
          payload.allow_api_keys = governance.allow_api_keys;
        }
        if (canSuspend) payload.is_active = draft.isActive;
        await updateTenant(settings, editing.id, payload);
        setSuccess(`Tenant ${draft.name} updated.`);
        await onAuthRefresh();
      }
      setEditing(null);
      await load();
    } catch (err) {
      setError(adminErrorMessage(err));
    } finally {
      setBusy(false);
    }
  }

  async function suspend() {
    if (!confirmSuspend) return;
    setBusy(true);
    setError("");
    try {
      await updateTenant(settings, confirmSuspend.id, { is_active: false });
      setSuccess(`${confirmSuspend.name} suspended.`);
      setConfirmSuspend(null);
      await onAuthRefresh();
      await load();
    } catch (err) {
      setError(adminErrorMessage(err));
    } finally {
      setBusy(false);
    }
  }

  const activeTenantId = (auth.active_tenant ?? auth.tenant).id;
  const systemAllowsCustomGroups = systemSettings?.allow_tenant_custom_groups !== false;
  const systemAllowsCustomRoles = systemSettings?.allow_tenant_custom_roles !== false;
  const systemAllowsApiKeys = systemSettings?.allow_tenant_api_keys !== false;
  const systemDeniedGovernance = [
    systemAllowsCustomGroups ? "" : "custom groups",
    systemAllowsCustomRoles ? "" : "custom roles",
    systemAllowsApiKeys ? "" : "API keys"
  ].filter(Boolean).join(", ");
  const columns = useMemo<DataGridColumn<TenantAdminItem>[]>(() => [
    { id: "name", header: "Tenant", width: "minmax(210px, 1fr)", minWidth: 190, resizable: true, sticky: "start", sortable: true, filterable: true, value: (row) => `${row.name} ${row.slug}`, render: (row) => <div><strong>{row.name}</strong><div className="muted small-note">{row.slug}</div></div> },
    { id: "users", header: "Users", width: 100, resizable: false, sortable: true, filterable: true, filterType: "integer", value: (row) => row.counts.users ?? 0, render: (row) => `${row.counts.active_users ?? 0}/${row.counts.users ?? 0}` },
    { id: "groups", header: "Groups", width: 95, resizable: false, sortable: true, filterable: true, filterType: "integer", value: (row) => row.counts.groups ?? 0 },
    { id: "campaigns", header: "Campaigns", width: 110, resizable: false, sortable: true, filterable: true, filterType: "integer", value: (row) => row.counts.campaigns ?? 0 },
    { id: "files", header: "Files", width: 90, resizable: false, sortable: true, filterable: true, filterType: "integer", value: (row) => row.counts.files ?? 0 },
    { id: "locale", header: "Locale", width: 120, minWidth: 90, maxWidth: 220, resizable: true, fill: true, sortable: true, filterable: true, value: (row) => row.default_locale },
    { id: "status", header: "Status", width: 120, resizable: false, sortable: true, filterable: true, value: (row) => row.is_active ? "active" : "inactive", render: (row) => <StatusBadge status={row.is_active ? "active" : "inactive"} /> },
    { id: "actions", header: "Actions", width: 150, sticky: "end", resizable: false, align: "right", render: (row) => <div className="admin-icon-actions">
      <AdminIconButton label={`Inspect ${row.name}`} icon={<Search />} onClick={() => setViewing(row)} />
      <AdminIconButton label={`Edit ${row.name}`} icon={<Pencil />} onClick={() => openEdit(row)} disabled={!canUpdate} />
      <AdminIconButton label={`Suspend ${row.name}`} icon={<Trash2 />} variant="danger" onClick={() => setConfirmSuspend(row)} disabled={!canSuspend || !row.is_active || row.id === activeTenantId} />
    </div> }
  ], [activeTenantId, canSuspend, canUpdate]);

  return (
    <>
      <AdminPageLayout
        title="Tenants"
        description="Create and govern tenant spaces. Suspension retains campaigns, files and audit evidence; the tenant backing the current session cannot be suspended."
        loading={loading}
        error={error}
        success={success}
        actions={<><Button onClick={() => void load()} disabled={loading}>Reload</Button><AdminIconButton label="Add tenant" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} /></>}
      >
        <div className="admin-table-surface"><DataGrid id="admin-tenants-v3" rows={tenants} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="No tenants found." /></div>
      </AdminPageLayout>

      <Dialog open={editing !== null} title={editing === "new" ? "Create tenant" : "Edit tenant"} onClose={() => !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<><Button onClick={() => setEditing(null)} disabled={busy}>Cancel</Button><Button variant="primary" onClick={() => void save()} disabled={!(editing === "new" ? canCreate : canUpdate) || busy || !draft.name.trim() || !draft.slug.trim() || (editing === "new" && !draft.ownerAccountId)}>{busy ? "Saving…" : "Save tenant"}</Button></>}>
        <div className="admin-form-grid two-columns">
          <FormField label="Name"><input value={draft.name} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, name: event.target.value })} /></FormField>
          <FormField label="Slug"><input value={draft.slug} disabled={editing !== "new" || !canCreate} onChange={(event) => setDraft({ ...draft, slug: event.target.value })} /></FormField>
          {editing === "new" && <FormField label="Initial tenant owner"><select value={draft.ownerAccountId} onChange={(event) => setDraft({ ...draft, ownerAccountId: event.target.value })}>{ownerCandidates.map((candidate) => <option key={candidate.account_id} value={candidate.account_id}>{candidate.display_name ? `${candidate.display_name} (${candidate.email})` : candidate.email}</option>)}</select></FormField>}
          <FormField label="Default locale"><input value={draft.defaultLocale} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, defaultLocale: event.target.value })} /></FormField>
          {editing !== "new" && <FormField label="Status"><select value={draft.isActive ? "active" : "inactive"} disabled={!canSuspend} onChange={(event) => setDraft({ ...draft, isActive: event.target.value === "active" })}><option value="active">Active</option><option value="inactive">Suspended</option></select></FormField>}
          <FormField label="Description"><textarea rows={4} value={draft.description} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, description: event.target.value })} /></FormField>
        </div>
        <h3>System governance overrides</h3>
        <div className="admin-form-grid two-columns">
          <GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsCustomGroups} label="Custom tenant groups" value={draft.customGroups} onChange={(customGroups) => setDraft({ ...draft, customGroups })} />
          <GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsCustomRoles} label="Custom tenant roles" value={draft.customRoles} onChange={(customRoles) => setDraft({ ...draft, customRoles })} />
          <GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsApiKeys} label="Tenant API keys" value={draft.apiKeys} onChange={(apiKeys) => setDraft({ ...draft, apiKeys })} />
        </div>
        <p className="muted small-note">Inherit follows the current system setting. Explicit deny narrows access; explicit allow is valid only while the system setting allows it.</p>
        {systemDeniedGovernance && <p className="muted small-note">Explicit allow is unavailable for {systemDeniedGovernance} because the current system setting denies it.</p>}
      </Dialog>

      <Dialog open={Boolean(viewing)} title="Tenant details" onClose={() => setViewing(null)} className="admin-dialog admin-dialog-wide" footer={<Button onClick={() => setViewing(null)}>Close</Button>}>
        {viewing && <><dl className="admin-details-grid">
          <div><dt>Tenant</dt><dd>{viewing.name}</dd></div><div><dt>Slug</dt><dd>{viewing.slug}</dd></div>
          <div><dt>Status</dt><dd>{viewing.is_active ? "Active" : "Suspended"}</dd></div><div><dt>Default locale</dt><dd>{viewing.default_locale}</dd></div>
          <div><dt>Created</dt><dd>{formatDateTime(viewing.created_at)}</dd></div><div><dt>Updated</dt><dd>{formatDateTime(viewing.updated_at)}</dd></div>
          <div><dt>Custom groups</dt><dd>{viewing.effective_governance.allow_custom_groups ? "Allowed" : "Denied"} ({fromOverride(viewing.allow_custom_groups)})</dd></div>
          <div><dt>Custom roles</dt><dd>{viewing.effective_governance.allow_custom_roles ? "Allowed" : "Denied"} ({fromOverride(viewing.allow_custom_roles)})</dd></div>
          <div><dt>API keys</dt><dd>{viewing.effective_governance.allow_api_keys ? "Allowed" : "Denied"} ({fromOverride(viewing.allow_api_keys)})</dd></div>
          <div><dt>Objects</dt><dd>{viewing.counts.users ?? 0} users, {viewing.counts.groups ?? 0} groups, {viewing.counts.campaigns ?? 0} campaigns, {viewing.counts.files ?? 0} files</dd></div>
        </dl>{viewing.description && <p>{viewing.description}</p>}</>}
      </Dialog>

      <ConfirmDialog open={Boolean(confirmSuspend)} title="Suspend tenant" message={`Suspend ${confirmSuspend?.name}? Existing data remains retained, but its members cannot use the tenant.`} confirmLabel="Suspend tenant" tone="danger" busy={busy} onCancel={() => setConfirmSuspend(null)} onConfirm={() => void suspend()} />
    </>
  );
}

function GovernanceSelect({ label, value, onChange, disabled = false, allowDisabled = false }: { label: string; value: OverrideValue; onChange: (value: OverrideValue) => void; disabled?: boolean; allowDisabled?: boolean }) {
  return <FormField label={label}><select value={value} disabled={disabled} onChange={(event) => onChange(event.target.value as OverrideValue)}><option value="inherit">Inherit system setting</option><option value="allow" disabled={allowDisabled}>Allow when system allows</option><option value="deny">Explicitly deny</option></select></FormField>;
}
