"use client";

import { useCallback, useState } from "react";
import { buildPublishPayload } from "../../../../lib/create/buildPublishPayload";
import { publishRule, updatePublishedRule } from "../../../../lib/create/api";
import { writeLastPublishedRule } from "../../../../lib/create/lastPublishedRule";
import messages from "../../../../messages/en/index";
import type { CreateFlowState } from "../types";
import {
  CREATE_FLOW_COMPLETED_CELEBRATE_QUERY,
  CREATE_FLOW_COMPLETED_CELEBRATE_VALUE,
} from "../utils/flowSteps";
import { createFlowStepPath } from "../utils/createFlowPaths";

type AppRouterLike = { push: (_href: string) => void };

type OpenLogin = (args: {
  variant: "default" | "saveProgress";
  nextPath: string;
  backdropVariant: "blurredYellow";
}) => void;

type SessionUser = { id: string; email: string };

export type UseCreateFlowFinalizeResult = {
  publishBannerMessage: string | null;
  setPublishBannerMessage: (_message: string | null) => void;
  isPublishing: boolean;
  finalize: () => Promise<void>;
};

/** Final Review → publish: banner + `isPublishing`, consumed by `CreateFlowLayoutClient`. */
export function useCreateFlowFinalize({
  state,
  router,
  openLogin,
  updateState,
  loginReturnPath,
  sessionUser,
  onGuestPublished,
}: {
  state: CreateFlowState;
  router: AppRouterLike;
  openLogin: OpenLogin;
  updateState: (_patch: Partial<CreateFlowState>) => void;
  /** Session gate return path (`?syncDraft=1`) — differs for `/create/edit-rule` vs `/create/final-review`. */
  loginReturnPath: string;
  /**
   * `undefined` while `/api/auth/session` is in flight — finalize is a no-op
   * until it resolves. `null` is a guest (anonymous publish).
   */
  sessionUser: SessionUser | null | undefined;
  /** Guest publish succeeded; `skippedInvites` when stakeholder emails were not sent. */
  onGuestPublished?: (_info: { skippedInvites: boolean }) => void;
}): UseCreateFlowFinalizeResult {
  const [publishBannerMessage, setPublishBannerMessage] = useState<
    string | null
  >(null);
  const [isPublishing, setIsPublishing] = useState(false);

  const finalize = useCallback(async () => {
    if (sessionUser === undefined) return;

    setPublishBannerMessage(null);
    const payloadResult = buildPublishPayload(state);
    if (payloadResult.ok === false) {
      setPublishBannerMessage(
        payloadResult.error === "missingCommunityName"
          ? messages.create.reviewAndComplete.publish.missingCommunityName
          : payloadResult.error,
      );
      return;
    }
    const { title, summary, document: ruleDocument } = payloadResult;
    setIsPublishing(true);

    const editingId =
      typeof state.editingPublishedRuleId === "string"
        ? state.editingPublishedRuleId.trim()
        : "";

    if (editingId.length > 0) {
      const updateResult = await updatePublishedRule(editingId, {
        title,
        summary: summary ?? null,
        document: ruleDocument,
      });
      setIsPublishing(false);
      if (updateResult.ok === true) {
        writeLastPublishedRule({
          id: editingId,
          title,
          summary: summary ?? null,
          document: ruleDocument,
        });
        updateState({ editingPublishedRuleId: undefined });
        router.push(createFlowStepPath("completed"));
        return;
      }
      if (updateResult.status === 401) {
        openLogin({
          variant: "default",
          nextPath: loginReturnPath,
          backdropVariant: "blurredYellow",
        });
        return;
      }
      setPublishBannerMessage(
        updateResult.error.trim() !== ""
          ? updateResult.error
          : messages.create.reviewAndComplete.publish.genericPublishFailed,
      );
      return;
    }

    const isGuest = sessionUser === null;
    const rawStakeholderEmails = (state.stakeholderEmails ?? []).filter(
      (e) => typeof e === "string" && e.trim() !== "",
    );
    const stakeholderEmails = isGuest ? [] : rawStakeholderEmails;
    const skippedGuestInvites = isGuest && rawStakeholderEmails.length > 0;

    const publishResult = await publishRule({
      title,
      summary,
      document: ruleDocument,
      ...(stakeholderEmails.length > 0 ? { stakeholderEmails } : {}),
    });
    setIsPublishing(false);
    if (publishResult.ok === true) {
      writeLastPublishedRule({
        id: publishResult.id,
        title,
        summary: summary ?? null,
        document: ruleDocument,
      });
      if (isGuest) {
        onGuestPublished?.({ skippedInvites: skippedGuestInvites });
      }
      router.push(
        createFlowStepPath("completed", {
          [CREATE_FLOW_COMPLETED_CELEBRATE_QUERY]:
            CREATE_FLOW_COMPLETED_CELEBRATE_VALUE,
        }),
      );
      return;
    }
    if (publishResult.status === 401) {
      openLogin({
        variant: "default",
        nextPath: loginReturnPath,
        backdropVariant: "blurredYellow",
      });
      return;
    }
    setPublishBannerMessage(
      publishResult.error.trim() !== ""
        ? publishResult.error
        : messages.create.reviewAndComplete.publish.genericPublishFailed,
    );
  }, [
    state,
    router,
    openLogin,
    updateState,
    loginReturnPath,
    sessionUser,
    onGuestPublished,
  ]);

  return {
    publishBannerMessage,
    setPublishBannerMessage,
    isPublishing,
    finalize,
  };
}
