import { useEffect, useState } from "react";
import type { ApiSettings } from "@govoplan/core-webui";
import { fetchGroups, fetchUsers, runRetentionPolicy, type PrivacyRetentionPolicyScope, type RetentionRunResponse } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { Card } from "@govoplan/core-webui";
import { ConfirmDialog } from "@govoplan/core-webui";
import { RetentionPolicyScopeManager, type RetentionPolicyTargetOption } from "@govoplan/core-webui";
import { AdminPageLayout, adminErrorMessage } from "@govoplan/core-webui";

type Props = {
  settings: ApiSettings;
  scopeType: Extract<PrivacyRetentionPolicyScope, "system" | "tenant" | "user" | "group">;
  canWrite: boolean;
};

const copy: Record<Props["scopeType"], { title: string; description: string; targetLabel?: string; policyTitle: string; policyDescription: string }> = {
  system: {
    title: "System retention",
    description: "Instance-wide privacy retention policy and lower-level override permissions.",
    policyTitle: "System retention policy",
    policyDescription: "Set concrete system retention values. The Allow override toggles decide which fields tenants, owners and campaigns may override."
  },
  tenant: {
    title: "Tenant retention",
    description: "Tenant-level privacy and retention limits for the active tenant.",
    policyTitle: "Tenant retention policy",
    policyDescription: "Tenant limits may only narrow the system policy. The Allow override toggles decide which fields users, groups and campaigns may override."
  },
  user: {
    title: "User retention",
    description: "User-scoped retention limits for campaigns owned by users in the active tenant.",
    targetLabel: "User",
    policyTitle: "User retention policy",
    policyDescription: "User limits may only narrow inherited system and tenant policy. The Allow override toggles decide which fields user-owned campaigns may override."
  },
  group: {
    title: "Group retention",
    description: "Group-scoped retention limits for group-owned campaigns in the active tenant.",
    targetLabel: "Group",
    policyTitle: "Group retention policy",
    policyDescription: "Group limits may only narrow inherited system and tenant policy. The Allow override toggles decide which fields group-owned campaigns may override."
  }
};

export default function RetentionPoliciesPanel({ settings, scopeType, canWrite }: Props) {
  const [targets, setTargets] = useState<RetentionPolicyTargetOption[]>([]);
  const [loadingTargets, setLoadingTargets] = useState(scopeType === "user" || scopeType === "group");
  const [targetError, setTargetError] = useState("");
  const [busy, setBusy] = useState(false);
  const [success, setSuccess] = useState("");
  const [runError, setRunError] = useState("");
  const [confirmRetentionRun, setConfirmRetentionRun] = useState(false);
  const [retentionResult, setRetentionResult] = useState<RetentionRunResponse | null>(null);

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

  async function loadTargets() {
    if (scopeType !== "user" && scopeType !== "group") {
      setTargets([]);
      setLoadingTargets(false);
      setTargetError("");
      return;
    }
    setLoadingTargets(true);
    setTargetError("");
    try {
      if (scopeType === "user") {
        const users = await fetchUsers(settings);
        setTargets(users.map((user) => ({
          id: user.id,
          label: user.display_name || user.email,
          secondary: user.display_name ? user.email : null
        })));
      } else {
        const groups = await fetchGroups(settings);
        setTargets(groups.map((group) => ({
          id: group.id,
          label: group.name,
          secondary: group.slug
        })));
      }
    } catch (err) {
      setTargets([]);
      setTargetError(adminErrorMessage(err));
    } finally {
      setLoadingTargets(false);
    }
  }

  async function runRetention(dryRun: boolean) {
    setBusy(true);
    setRunError("");
    setSuccess("");
    try {
      const response = await runRetentionPolicy(settings, dryRun);
      setRetentionResult(response);
      setSuccess(dryRun ? "Retention dry run completed." : "Retention policy applied.");
      setConfirmRetentionRun(false);
    } catch (err) { setRunError(adminErrorMessage(err)); }
    finally { setBusy(false); }
  }

  const labels = copy[scopeType];

  return (
    <>
      <AdminPageLayout title={labels.title} description={labels.description} loading={loadingTargets} error={targetError || runError} success={success}>
        <RetentionPolicyScopeManager
          settings={settings}
          scopeType={scopeType}
          targetOptions={targets}
          targetLabel={labels.targetLabel}
          title={labels.policyTitle}
          description={labels.policyDescription}
          canWrite={canWrite}
        />
        {scopeType === "system" && (
          <div className="retention-run-card">
            <Card title="Retention execution">
              <p className="muted small-note">Run the saved effective retention policy against stored raw JSON, generated EML, report detail, mock mailbox content and audit detail.</p>
              <div className="button-row compact-actions subsection-bottom-actions">
                <Button onClick={() => void runRetention(true)} disabled={!canWrite || busy}>Dry run</Button>
                <Button variant="danger" onClick={() => setConfirmRetentionRun(true)} disabled={!canWrite || busy}>Apply retention</Button>
              </div>
              {retentionResult && <pre className="admin-json-preview">{JSON.stringify(retentionResult.result, null, 2)}</pre>}
            </Card>
          </div>
        )}
      </AdminPageLayout>
      <ConfirmDialog
        open={confirmRetentionRun}
        title="Apply retention policy"
        message="This will redact or delete eligible retained data according to the saved policy. Run a dry run first if the counts have not been reviewed."
        confirmLabel="Apply retention"
        tone="danger"
        busy={busy}
        onCancel={() => setConfirmRetentionRun(false)}
        onConfirm={() => void runRetention(false)}
      />
    </>
  );
}
