import { useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import type { ApiSettings } from "../../types";
import Button from "../../components/Button";
import Card from "../../components/Card";
import ConfirmDialog from "../../components/ConfirmDialog";
import FormField from "../../components/FormField";
import LoadingFrame from "../../components/LoadingFrame";
import MetricCard from "../../components/MetricCard";
import PageTitle from "../../components/PageTitle";
import StatusBadge from "../../components/StatusBadge";
import DismissibleAlert from "../../components/DismissibleAlert";
import DataGrid, { type DataGridColumn } from "../../components/table/DataGrid";
import {
  lockCampaignVersionPermanently,
  lockCampaignVersionTemporarily,
  unlockCampaignVersionUserLock,
  updateCampaignMetadata,
  type CampaignVersionListItem,
} from "../../api/campaigns";
import { useCampaignWorkspaceData } from "./hooks/useCampaignWorkspaceData";
import {
  canUnlockValidationVersion,
  formatDateTime,
  isFinalLockedVersion,
  isPermanentUserLockedVersion,
  isTemporaryUserLockedVersion,
  isVersionReadyForDelivery,
  summaryValue,
} from "./utils/campaignView";

const campaignModeOptions = ["draft", "test", "send"];
type LockAction = "temporary" | "unlock" | "permanent";
type PendingLockAction = { version: CampaignVersionListItem; action: LockAction } | null;

export default function CampaignOverviewPage({ settings, campaignId }: { settings: ApiSettings; campaignId: string }) {
  const { data, loading, error, reload, setError } = useCampaignWorkspaceData(settings, campaignId, { includeSummary: true });
  const campaign = data.campaign;
  const versions = useMemo(() => data.versions.slice().sort((a, b) => (b.version_number ?? 0) - (a.version_number ?? 0)), [data.versions]);
  const [identity, setIdentity] = useState({ external_id: "", name: "", status: "", description: "" });
  const [identityDirty, setIdentityDirty] = useState(false);
  const [savingIdentity, setSavingIdentity] = useState(false);
  const [pendingLockAction, setPendingLockAction] = useState<PendingLockAction>(null);
  const [lockBusy, setLockBusy] = useState(false);
  const [message, setMessage] = useState("");

  useEffect(() => {
    if (!campaign || identityDirty) return;
    setIdentity({
      external_id: campaign.external_id ?? "",
      name: campaign.name ?? "",
      status: campaign.status ?? "",
      description: campaign.description ?? "",
    });
  }, [campaign, identityDirty]);

  function patchIdentity(key: keyof typeof identity, value: string) {
    setIdentity((current) => ({ ...current, [key]: value }));
    setIdentityDirty(true);
    setMessage("");
  }

  async function saveIdentity() {
    if (!campaign || savingIdentity || !identityDirty) return;
    setSavingIdentity(true);
    setError("");
    setMessage("");
    try {
      await updateCampaignMetadata(settings, campaign.id, {
        external_id: identity.external_id,
        name: identity.name,
        status: identity.status,
        description: identity.description,
      });
      setIdentityDirty(false);
      await reload();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSavingIdentity(false);
    }
  }

  async function applyLockAction() {
    const pending = pendingLockAction;
    if (!pending || lockBusy) return;
    setLockBusy(true);
    setError("");
    setMessage("");
    try {
      if (pending.action === "temporary") {
        await lockCampaignVersionTemporarily(settings, campaignId, pending.version.id);
        setMessage(`Version #${pending.version.version_number} temporarily locked.`);
      } else if (pending.action === "unlock") {
        await unlockCampaignVersionUserLock(settings, campaignId, pending.version.id);
        setMessage(`Temporary lock removed from version #${pending.version.version_number}.`);
      } else {
        await lockCampaignVersionPermanently(settings, campaignId, pending.version.id);
        setMessage(`Version #${pending.version.version_number} permanently locked.`);
      }
      setPendingLockAction(null);
      await reload();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLockBusy(false);
    }
  }

  return (
    <div className="content-pad workspace-data-page">
      <div className="page-heading split workspace-heading">
        <div>
          <PageTitle loading={loading}>{campaign?.name || "Overview"}</PageTitle>
          <p className="mono-small">Campaign overview · version-independent identity and version history</p>
        </div>
        <div className="button-row compact-actions">
          <Button onClick={reload} disabled={loading || savingIdentity || lockBusy}>Reload</Button>
          <Link to="wizard/create"><Button>Edit with wizard</Button></Link>
          <Button variant="primary" onClick={() => void saveIdentity()} disabled={!campaign || !identityDirty || savingIdentity}>{savingIdentity ? "Saving…" : "Save"}</Button>
        </div>
      </div>

      {error && <DismissibleAlert tone="danger" resetKey={error} floating>{error}</DismissibleAlert>}
      {message && <DismissibleAlert tone="success" resetKey={message} floating>{message}</DismissibleAlert>}

      <LoadingFrame loading={loading} label="Loading campaign overview…">
        <div className="metric-grid campaign-overview-metrics">
          <MetricCard label="Queueable" value={data.summary?.cards?.queueable ?? "—"} tone="good" detail="Ready or warning" />
          <MetricCard label="Needs attention" value={data.summary?.cards?.needs_attention ?? "—"} tone="warning" detail="Review first" />
          <MetricCard label="Sent" value={data.summary?.cards?.sent ?? "—"} tone="info" detail="SMTP success" />
          <MetricCard label="Failed" value={data.summary?.cards?.failed ?? "—"} tone="danger" detail="SMTP failures" />
        </div>

        <Card title="Campaign identity">
          <div className="form-grid campaign-identity-grid">
            <FormField label="Campaign ID">
              <input value={identity.external_id} onChange={(event) => patchIdentity("external_id", event.target.value)} />
            </FormField>
            <FormField label="Mode">
              <select value={identity.status} onChange={(event) => patchIdentity("status", event.target.value)}>
                {campaignModeOptions.map((option) => <option key={option} value={option}>{option}</option>)}
              </select>
            </FormField>
            <FormField label="Name">
              <input value={identity.name} onChange={(event) => patchIdentity("name", event.target.value)} />
            </FormField>
            <FormField label="Description">
              <textarea rows={4} value={identity.description} onChange={(event) => patchIdentity("description", event.target.value)} />
            </FormField>
          </div>
        </Card>

        <Card title="Version history">
          <DataGrid
            id={`campaign-${campaignId}-versions`}
            rows={versions}
            columns={versionColumns(setPendingLockAction, campaign?.current_version_id)}
            getRowKey={(version) => version.id}
            emptyText="No versions found."
            className="version-history-table"
            rowClassName={(version) => version.id === data.currentVersion?.id ? "current-version-row" : undefined}
          />
        </Card>

        <Card title="Current version state">
          <div className="summary-grid overview-summary-grid">
            <SummaryTile label="Validation errors" value={summaryValue(data.currentVersion?.validation_summary, ["error_count", "errors", "blocked"])} />
            <SummaryTile label="Warnings" value={summaryValue(data.currentVersion?.validation_summary, ["warning_count", "warnings"])} />
            <SummaryTile label="Built messages" value={summaryValue(data.currentVersion?.build_summary, ["built_count", "built", "messages_built"])} />
            <SummaryTile label="Jobs total" value={data.summary?.cards?.jobs_total ?? "—"} />
          </div>
        </Card>
      </LoadingFrame>

      <ConfirmDialog
        open={Boolean(pendingLockAction)}
        title={lockDialogTitle(pendingLockAction)}
        message={lockDialogMessage(pendingLockAction)}
        confirmLabel={lockDialogLabel(pendingLockAction)}
        tone={pendingLockAction?.action === "unlock" ? "default" : "danger"}
        busy={lockBusy}
        onCancel={() => setPendingLockAction(null)}
        onConfirm={() => void applyLockAction()}
      />
    </div>
  );
}

function versionColumns(setPendingLockAction: (action: PendingLockAction) => void, currentVersionId?: string | null): DataGridColumn<CampaignVersionListItem>[] {
  return [
    { id: "version", header: "Version", width: 110, sortable: true, filterable: true, sticky: "start", render: (version) => `#${version.version_number}`, value: (version) => version.version_number ?? 0 },
    { id: "state", header: "State", width: 140, sortable: true, filterable: true, render: (version) => <StatusBadge status={version.workflow_state ?? "editing"} />, value: (version) => version.workflow_state ?? "editing" },
    { id: "lock", header: "Lock", width: 190, sortable: true, filterable: true, render: (version) => versionLockLabel(version, currentVersionId), value: (version) => versionLockLabel(version, currentVersionId) },
    { id: "validation", header: "Validation", width: 170, sortable: true, filterable: true, render: validationLabel, value: validationLabel },
    { id: "build", header: "Build", width: 140, sortable: true, filterable: true, render: buildLabel, value: buildLabel },
    { id: "updated", header: "Updated", width: 190, sortable: true, filterable: true, render: (version) => formatDateTime(version.updated_at), value: (version) => version.updated_at ?? "" },
    {
      id: "actions",
      header: "Actions",
      width: 310,
      sticky: "end",
      render: (version) => {
        const isCurrent = version.id === currentVersionId;
        return (
          <div className="button-row compact-actions">
            <Link to={`send?version=${version.id}`}><Button variant={isCurrent ? "primary" : "secondary"}>Open</Button></Link>
            {isCurrent && (isTemporaryUserLockedVersion(version) ? (
              <>
                <Button onClick={() => setPendingLockAction({ version, action: "unlock" })}>Unlock</Button>
                <Button variant="danger" onClick={() => setPendingLockAction({ version, action: "permanent" })}>Lock permanently</Button>
              </>
            ) : !isPermanentUserLockedVersion(version) && !isFinalLockedVersion(version) && !canUnlockValidationVersion(version) && !version.locked_at ? (
              <Button onClick={() => setPendingLockAction({ version, action: "temporary" })}>Lock</Button>
            ) : null)}
          </div>
        );
      },
    },
  ];
}

function versionLockLabel(version: CampaignVersionListItem, currentVersionId?: string | null): string {
  if (currentVersionId && version.id !== currentVersionId) return "Historical · review-only";
  if (isTemporaryUserLockedVersion(version)) return "Temporary user lock";
  if (isPermanentUserLockedVersion(version)) return "Permanent user lock";
  if (isFinalLockedVersion(version)) return "Permanent delivery lock";
  if (canUnlockValidationVersion(version)) return "Temporary validation lock";
  if (version.locked_at) return "Temporarily locked";
  return "Editable";
}

function validationLabel(version: CampaignVersionListItem): string {
  const validation = version.validation_summary ?? {};
  if (validation.ok === true && isVersionReadyForDelivery(version)) return "Passed";
  if (validation.ok === false) return "Needs attention";
  if (validation.ok === true) return "Passed, unavailable while user-locked";
  return "Not validated";
}

function buildLabel(version: CampaignVersionListItem): string {
  const build = version.build_summary ?? {};
  return String(build.built_count ?? build.ready_count ?? "Not built");
}

function lockDialogTitle(pending: PendingLockAction): string {
  if (pending?.action === "temporary") return "Temporarily lock version?";
  if (pending?.action === "unlock") return "Unlock version?";
  if (pending?.action === "permanent") return "Lock version permanently?";
  return "Confirm lock action";
}

function lockDialogMessage(pending: PendingLockAction): string {
  if (pending?.action === "temporary") {
    return "This makes the version read-only without making it final. An authorized user may unlock it later or make the lock permanent.";
  }
  if (pending?.action === "unlock") {
    return "This removes the temporary user lock and makes the version editable again. Existing validation/build state is otherwise retained.";
  }
  if (pending?.action === "permanent") {
    return "This lock cannot be removed by any role. The version remains reviewable for audit purposes; future changes require an editable copy.";
  }
  return "Continue?";
}

function lockDialogLabel(pending: PendingLockAction): string {
  if (pending?.action === "temporary") return "Lock temporarily";
  if (pending?.action === "unlock") return "Unlock";
  if (pending?.action === "permanent") return "Lock permanently";
  return "Confirm";
}

function SummaryTile({ label, value }: { label: string; value: string | number }) {
  return (
    <div className="summary-tile">
      <span>{label}</span>
      <strong>{value}</strong>
    </div>
  );
}
