import { useState } from "react";
import type { ApiSettings } from "../../../types";
import Button from "../../../components/Button";
import ConfirmDialog from "../../../components/ConfirmDialog";
import DismissibleAlert from "../../../components/DismissibleAlert";
import {
  forkCampaignVersion,
  lockCampaignVersionPermanently,
  unlockCampaignVersionUserLock,
  unlockCampaignVersionValidation,
  type CampaignVersionDetail,
  type CampaignVersionListItem,
} from "../../../api/campaigns";
import {
  canUnlockValidationVersion,
  formatDateTime,
  isFinalLockedVersion,
  isHistoricalCampaignVersion,
  isPermanentUserLockedVersion,
  isTemporaryUserLockedVersion,
} from "../utils/campaignView";

type LockedVersionNoticeProps = {
  settings: ApiSettings;
  campaignId: string;
  version: CampaignVersionDetail | CampaignVersionListItem | null;
  currentVersionId?: string | null;
  reload: () => Promise<void>;
  message?: string;
};

type ConfirmAction = "unlock-validation" | "unlock-user" | "permanent" | null;

export default function LockedVersionNotice({ settings, campaignId, version, currentVersionId, reload, message }: LockedVersionNoticeProps) {
  const [busy, setBusy] = useState(false);
  const [localError, setLocalError] = useState("");
  const [localMessage, setLocalMessage] = useState("");
  const [confirmAction, setConfirmAction] = useState<ConfirmAction>(null);

  const historicalVersion = isHistoricalCampaignVersion(version, currentVersionId);
  const validationLock = !historicalVersion && canUnlockValidationVersion(version);
  const temporaryUserLock = !historicalVersion && isTemporaryUserLockedVersion(version);
  const permanentUserLock = isPermanentUserLockedVersion(version);
  const finalLock = isFinalLockedVersion(version);
  const canCreateEditableCopy = !historicalVersion && (permanentUserLock || finalLock);
  const presentation = lockPresentation(version, {
    historicalVersion,
    validationLock,
    temporaryUserLock,
    permanentUserLock,
    finalLock,
  });

  async function runAction(action: Exclude<ConfirmAction, null>) {
    if (!version || busy) return;
    setBusy(true);
    setLocalError("");
    setLocalMessage("");
    try {
      if (action === "unlock-validation") {
        await unlockCampaignVersionValidation(settings, campaignId, version.id);
        setLocalMessage("Validation lock removed. Validation, build and generated queue state were invalidated.");
      } else if (action === "unlock-user") {
        await unlockCampaignVersionUserLock(settings, campaignId, version.id);
        setLocalMessage("Temporary user lock removed. The version is editable again.");
      } else {
        await lockCampaignVersionPermanently(settings, campaignId, version.id);
        setLocalMessage("Version permanently locked. Future changes require an editable copy.");
      }
      await reload();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusy(false);
    }
  }

  async function createEditableCopy() {
    if (!version || busy) return;
    setBusy(true);
    setLocalError("");
    setLocalMessage("");
    try {
      const result = await forkCampaignVersion(settings, campaignId, version.id, {
        current_flow: "manual",
        current_step: version.current_step ?? null,
      });
      setLocalMessage(`Created editable version #${result.version.version_number}.`);
      await reload();
    } catch (err) {
      setLocalError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusy(false);
    }
  }

  return (
    <DismissibleAlert tone="info" dismissible={false} className={`locked-version-notice lock-kind-${presentation.kind}`}>
      <div className="locked-version-copy">
        <strong>{presentation.title}</strong>{" "}
        <span>{presentation.description}</span>
        {message && <span className="locked-version-context"> {message}</span>}
        {presentation.info && <span className="locked-version-reason"> {presentation.info}</span>}
        {localMessage && <span className="locked-version-feedback"> {localMessage}</span>}
        {localError && <span className="locked-version-error"> {localError}</span>}
      </div>
      <div className="button-row compact-actions locked-version-actions">
        {validationLock && (
          <Button onClick={() => setConfirmAction("unlock-validation")} disabled={!version || busy}>
            {busy ? "Working…" : "Unlock validation"}
          </Button>
        )}
        {temporaryUserLock && (
          <>
            <Button onClick={() => setConfirmAction("unlock-user")} disabled={!version || busy}>
              {busy ? "Working…" : "Unlock"}
            </Button>
            <Button variant="danger" onClick={() => setConfirmAction("permanent")} disabled={!version || busy}>
              Lock permanently
            </Button>
          </>
        )}
        {canCreateEditableCopy && (
          <Button variant="primary" onClick={() => void createEditableCopy()} disabled={!version || busy}>
            {busy ? "Creating copy…" : "Create editable copy"}
          </Button>
        )}
      </div>

      <ConfirmDialog
        open={confirmAction !== null}
        title={confirmDialogTitle(confirmAction)}
        message={confirmDialogMessage(confirmAction)}
        confirmLabel={confirmDialogLabel(confirmAction)}
        tone={confirmAction === "unlock-user" ? "default" : "danger"}
        busy={busy}
        onCancel={() => setConfirmAction(null)}
        onConfirm={() => {
          const action = confirmAction;
          setConfirmAction(null);
          if (action) void runAction(action);
        }}
      />
    </DismissibleAlert>
  );
}

type LockFlags = {
  historicalVersion: boolean;
  validationLock: boolean;
  temporaryUserLock: boolean;
  permanentUserLock: boolean;
  finalLock: boolean;
};

function lockPresentation(
  version: CampaignVersionDetail | CampaignVersionListItem | null,
  flags: LockFlags,
): { kind: string; title: string; description: string; info: string } {
  if (flags.historicalVersion) {
    return {
      kind: "historical",
      title: "Historical version.",
      description: "This version is review-only. Only the campaign's current working version may be edited in place.",
      info: `Version #${version?.version_number ?? "—"}.`,
    };
  }
  if (flags.temporaryUserLock) {
    return {
      kind: "temporary-user",
      title: "Temporarily locked version.",
      description: "Campaign data is read-only, but an authorized user may unlock it or make the lock permanent.",
      info: version?.user_locked_at ? `Locked ${formatDateTime(version.user_locked_at)}.` : "",
    };
  }
  if (flags.permanentUserLock) {
    return {
      kind: "permanent-user",
      title: "Permanently locked version.",
      description: "This user-requested snapshot cannot be unlocked. Create an editable copy for future changes.",
      info: version?.user_locked_at || version?.published_at
        ? `Locked ${formatDateTime(version.user_locked_at ?? version.published_at)}.`
        : "",
    };
  }
  if (flags.validationLock) {
    return {
      kind: "validation",
      title: "Temporarily locked after validation.",
      description: "This protects the validated build input. Unlocking invalidates validation, build and generated queue state.",
      info: version?.locked_at ? `Validated ${formatDateTime(version.locked_at)}.` : "",
    };
  }
  if (flags.finalLock) {
    return {
      kind: "delivery",
      title: "Permanently locked delivery snapshot.",
      description: "Delivery has started or the version is in a final state, so it cannot be unlocked in place.",
      info: version?.locked_at ? `Locked ${formatDateTime(version.locked_at)}.` : "",
    };
  }
  return {
    kind: "other",
    title: "Locked version.",
    description: "This version is read-only. Create an editable copy to continue working.",
    info: version?.locked_at ? `Locked ${formatDateTime(version.locked_at)}.` : "",
  };
}

function confirmDialogTitle(action: ConfirmAction): string {
  if (action === "unlock-validation") return "Unlock validation?";
  if (action === "unlock-user") return "Unlock temporary lock?";
  if (action === "permanent") return "Lock permanently?";
  return "Confirm action";
}

function confirmDialogMessage(action: ConfirmAction): string {
  if (action === "unlock-validation") {
    return "This makes the version editable and clears validation, build results, review acknowledgement and generated jobs for this version.";
  }
  if (action === "unlock-user") {
    return "This removes the reversible user lock. Campaign data and existing workflow results are not otherwise changed.";
  }
  if (action === "permanent") {
    return "This lock cannot be removed by any role. The version remains available for review and audit, but future changes require an editable copy.";
  }
  return "Continue?";
}

function confirmDialogLabel(action: ConfirmAction): string {
  if (action === "unlock-validation") return "Unlock validation";
  if (action === "unlock-user") return "Unlock";
  if (action === "permanent") return "Lock permanently";
  return "Confirm";
}
