/**
 * Step definitions and helpers for the Create Rule Flow
 *
 * Single source of truth for step order and navigation helpers.
 * Order matches Figma Create Community (frames 1–8) then later stages.
 * `community-structure` precedes `community-context` and `community-size` (Figma frame 3 vs 5 swap).
 */

import type { CreateFlowStep } from "../types";

/**
 * Ordered list of steps in the create rule flow
 */
export const FLOW_STEP_ORDER: readonly CreateFlowStep[] = [
  "informational",
  "community-name",
  "community-structure",
  "community-context",
  "community-size",
  "community-upload",
  "community-save",
  "review",
  "core-values",
  "communication-methods",
  "membership-methods",
  "decision-approaches",
  "conflict-management",
  "confirm-stakeholders",
  "final-review",
  "completed",
] as const;

/**
 * Valid URL segments for `/create/[screenId]` (includes branch-only `edit-rule`).
 * Linear order for navigation remains {@link FLOW_STEP_ORDER}.
 */
export const VALID_STEPS: readonly CreateFlowStep[] = [
  ...FLOW_STEP_ORDER,
  "edit-rule",
] as const;

/**
 * First step in the flow (entry point)
 */
export const FIRST_STEP: CreateFlowStep = FLOW_STEP_ORDER[0];

/** Options for navigation when the email / magic-link save step is not shown (signed-in users). */
export type CreateFlowNavigationOptions = {
  skipCommunitySave?: boolean;
};

/**
 * Returns the next step in the flow, or null if current is last/invalid
 */
export function getNextStep(
  currentStep: CreateFlowStep | null | undefined,
  options?: CreateFlowNavigationOptions,
): CreateFlowStep | null {
  if (!currentStep) return null;
  const index = FLOW_STEP_ORDER.indexOf(currentStep);
  if (index === -1 || index === FLOW_STEP_ORDER.length - 1) return null;
  const next = FLOW_STEP_ORDER[index + 1] as CreateFlowStep;
  if (options?.skipCommunitySave && next === "community-save") {
    return getNextStep("community-save", options);
  }
  return next;
}

/**
 * Returns the previous step in the flow, or null if current is first/invalid
 */
export function getPreviousStep(
  currentStep: CreateFlowStep | null | undefined,
  options?: CreateFlowNavigationOptions,
): CreateFlowStep | null {
  if (!currentStep) return null;
  const index = FLOW_STEP_ORDER.indexOf(currentStep);
  if (index <= 0) return null;
  const prev = FLOW_STEP_ORDER[index - 1] as CreateFlowStep;
  if (options?.skipCommunitySave && prev === "community-save") {
    return getPreviousStep("community-save", options);
  }
  return prev;
}

/**
 * Where the create-flow footer Back action should go. Usually the previous
 * step in {@link FLOW_STEP_ORDER}; when the user reached `confirm-stakeholders`
 * via template **Use without changes**, Back returns to template review instead
 * of `conflict-management` (that segment was skipped).
 */
export type CreateFlowBackTarget =
  | { kind: "step"; step: CreateFlowStep }
  | { kind: "templateReview"; slug: string };

export function resolveCreateFlowBackTarget(
  currentStep: CreateFlowStep | null | undefined,
  options: CreateFlowNavigationOptions | undefined,
  templateReviewBackSlug: string | undefined | null,
): CreateFlowBackTarget | null {
  const slug =
    typeof templateReviewBackSlug === "string"
      ? templateReviewBackSlug.trim()
      : "";
  if (currentStep === "confirm-stakeholders" && slug.length > 0) {
    return { kind: "templateReview", slug };
  }
  const prev = getPreviousStep(currentStep, options);
  return prev != null ? { kind: "step", step: prev } : null;
}

/**
 * Returns the index of the step (0-based), or -1 if invalid
 */
export function getStepIndex(step: CreateFlowStep | null | undefined): number {
  if (!step) return -1;
  return FLOW_STEP_ORDER.indexOf(step);
}

/**
 * Steps where below `lg` the main column scrolls with split layout
 * (`CreateFlowLayoutClient` — Linear CR-92 §4).
 */
export const CREATE_FLOW_SELECT_SPLIT_SCROLL_STEPS: readonly CreateFlowStep[] = [
  "community-size",
  "community-structure",
  "core-values",
  "decision-approaches",
] as const;

export function createFlowStepUsesSelectSplitScroll(
  step: CreateFlowStep | null | undefined,
): boolean {
  if (!step) return false;
  return (CREATE_FLOW_SELECT_SPLIT_SCROLL_STEPS as readonly string[]).includes(
    step,
  );
}

/**
 * Whether the given string is a valid create flow step
 */
export function isValidStep(
  step: string | null | undefined,
): step is CreateFlowStep {
  return (
    typeof step === "string" &&
    (VALID_STEPS as readonly string[]).includes(step)
  );
}

/**
 * Parses `/create/{screenId}` (and optional trailing segments) from pathname.
 * Returns null for non-wizard paths (e.g. `/create/review-template/...`).
 */
export function parseCreateFlowScreenFromPathname(
  pathname: string | null,
): CreateFlowStep | null {
  if (!pathname || pathname.length === 0) return null;
  if (pathname.includes("/create/review-template/")) return null;

  const parts = pathname.split("/").filter(Boolean);
  const createIdx = parts.indexOf("create");
  if (createIdx === -1 || createIdx >= parts.length - 1) return null;

  const segment = parts[createIdx + 1];
  if (segment === "review-template") return null;

  return isValidStep(segment) ? segment : null;
}

/** Same query as `/templates?fromFlow=1` — template was picked after `/create/review`. */
export const TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY = "fromFlow" as const;
export const TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE = "1" as const;

/**
 * Only set from `/create/review` “Create from template” with `fromFlow=1`.
 * Enables facet-ranked `GET /api/templates` + “RECOMMENDED” on the grid; omit
 * on profile and marketing so stale localStorage facets never show badges.
 */
export const TEMPLATES_FACET_RECOMMEND_QUERY = "recommendTemplates" as const;
export const TEMPLATES_FACET_RECOMMEND_VALUE = "1" as const;

/** `/create/completed?celebrate=1` — post-finalize toast; set only after **initial** POST publish, not PATCH updates. */
export const CREATE_FLOW_COMPLETED_CELEBRATE_QUERY = "celebrate" as const;
export const CREATE_FLOW_COMPLETED_CELEBRATE_VALUE = "1" as const;

/** `/create/{step}?reviewReturn=…` — set when opening a custom-rule step from final-review or edit-rule via + */
export const CREATE_FLOW_REVIEW_RETURN_QUERY_KEY = "reviewReturn" as const;

/**
 * `/create/confirm-stakeholders?manageStakeholders=1` — edit published rule invites (requires `state.editingPublishedRuleId`).
 * Typically paired with `reviewReturn=edit-rule`.
 */
export const CREATE_FLOW_MANAGE_STAKEHOLDERS_QUERY = "manageStakeholders" as const;
export const CREATE_FLOW_MANAGE_STAKEHOLDERS_VALUE = "1" as const;

export type CreateFlowReviewReturnTarget = "final-review" | "edit-rule";

export function parseReviewReturnSearchParam(
  searchParams: { get: (name: string) => string | null } | null | undefined,
): CreateFlowReviewReturnTarget | null {
  if (!searchParams) return null;
  const raw = searchParams.get(CREATE_FLOW_REVIEW_RETURN_QUERY_KEY);
  if (raw === "final-review" || raw === "edit-rule") return raw;
  return null;
}

/**
 * `/create/review-template/{slug}` with optional marker so chrome can send
 * footer Back to `/create/review` instead of marketing home.
 */
export function buildTemplateReviewHref(
  slug: string,
  options?: { fromCreateWizard?: boolean },
): string {
  const path = `/create/review-template/${encodeURIComponent(slug)}`;
  if (options?.fromCreateWizard) {
    return `${path}?${TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY}=${TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE}`;
  }
  return path;
}
