import { useState } from "react";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";

import type { components } from "../api/schema";
import { useSetVisibility, VisibilityError } from "../api/queries";
import { adjacentTransitions, type Visibility } from "./transitions";
import { Button } from "@/components/ui/button";
import {
  AlertDialog,
  AlertDialogTrigger,
  AlertDialogContent,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogCancel,
  AlertDialogAction,
} from "@/components/ui/alert-dialog";

type AdminObjectView = components["schemas"]["AdminObjectView"];

const STEPS: Visibility[] = ["draft", "internal", "public"];

export function PublishControl({ object }: { object: AdminObjectView }) {
  const { t } = useTranslation();
  const current = object.visibility;
  const { forward, back } = adjacentTransitions(current);
  const setVisibility = useSetVisibility();
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [errorKind, setErrorKind] = useState<"gate" | "illegal" | "other" | null>(null);

  const go = (visibility: Visibility) => {
    setErrorKind(null);
    setVisibility.mutate(
      { id: object.id, visibility },
      {
        onSuccess: () => setConfirmOpen(false),
        onError: (err) => {
          setConfirmOpen(false);
          const status = err instanceof VisibilityError ? err.status : 0;
          setErrorKind(status === 422 ? "gate" : status === 409 ? "illegal" : "other");
        },
      },
    );
  };

  const currentIndex = STEPS.indexOf(current);

  return (
    <section className="border-t p-4">
      <div className="mb-2 label-caption">
        {t("publish.heading")}
      </div>

      <div className="mb-3 flex">
        {STEPS.map((step, i) => (
          <div
            key={step}
            aria-current={i === currentIndex ? "step" : undefined}
            className={`flex-1 border px-2 py-1 text-center text-xs ${
              i === currentIndex
                ? "bg-primary font-semibold text-primary-foreground"
                : i < currentIndex
                  ? "bg-muted text-muted-foreground"
                  : "text-muted-foreground"
            }`}
          >
            {t(`visibility.${step}`)}
          </div>
        ))}
      </div>

      <div className="flex gap-2">
        {back && (
          <Button
            variant="ghost"
            size="sm"
            disabled={setVisibility.isPending}
            onClick={() => go(back)}
          >
            {back === "draft" ? t("publish.backToDraft") : t("publish.unpublishInternal")}
          </Button>
        )}
        {forward === "internal" && (
          <Button
            size="sm"
            disabled={setVisibility.isPending}
            onClick={() => go("internal")}
          >
            {t("publish.advanceInternal")}
          </Button>
        )}
        {forward === "public" && (
          <AlertDialog open={confirmOpen} onOpenChange={setConfirmOpen}>
            <AlertDialogTrigger
              render={
                <Button size="sm" disabled={setVisibility.isPending}>
                  {t("publish.publish")}
                </Button>
              }
            />
            <AlertDialogContent>
              <AlertDialogTitle>{t("publish.confirmTitle")}</AlertDialogTitle>
              <AlertDialogDescription>{t("publish.confirmBody")}</AlertDialogDescription>
              <AlertDialogFooter>
                <AlertDialogCancel>{t("form.cancel")}</AlertDialogCancel>
                <AlertDialogAction
                  disabled={setVisibility.isPending}
                  onClick={() => go("public")}
                >
                  {t("publish.confirm")}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        )}
      </div>

      {errorKind === "gate" && (
        <p role="alert" className="mt-2 text-sm text-destructive">
          {t("publish.gateError")}{" "}
          <Link to={`/objects/${object.id}/edit`} className="underline">
            {t("publish.editLink")}
          </Link>
        </p>
      )}
      {errorKind === "illegal" && (
        <p role="alert" className="mt-2 text-sm text-destructive">
          {t("publish.illegalError")}
        </p>
      )}
      {errorKind === "other" && (
        <p role="alert" className="mt-2 text-sm text-destructive">
          {t("form.rejected")}
        </p>
      )}
    </section>
  );
}
