// SPEC: PJ2026-010606 GitHub入口 draft-2026-06-25-gh-split

import { repoParts } from "./auth-and-safety";
import { commandError, errorPayload, githubGraphqlRequest, githubRequest, isGitHubError, validationError } from "./client";
import { prCompactSummary } from "./pr-summary";
import type { GitHubCommandResult, GitHubPullRequest } from "./types";

interface ReadyPullRequestGraphql {
  id?: string;
  number?: number;
  title?: string;
  state?: string;
  isDraft?: boolean;
  url?: string;
  headRefName?: string | null;
  baseRefName?: string | null;
  updatedAt?: string | null;
}

interface ReadyPullRequestMutation {
  markPullRequestReadyForReview?: {
    pullRequest?: ReadyPullRequestGraphql | null;
  } | null;
}

function mutationPlan(): Record<string, unknown> {
  return {
    method: "POST",
    path: "/graphql",
    mutation: "markPullRequestReadyForReview",
    variables: { pullRequestId: "present" },
  };
}

function readyPullRequestSummary(pr: ReadyPullRequestGraphql, fallback: GitHubPullRequest): Record<string, unknown> {
  return {
    id: pr.id ?? fallback.node_id ?? null,
    number: pr.number ?? fallback.number,
    title: pr.title ?? fallback.title,
    state: (pr.state ?? fallback.state).toLowerCase(),
    stateDetail: (pr.state ?? fallback.state).toLowerCase(),
    draft: pr.isDraft ?? false,
    url: pr.url ?? fallback.html_url,
    head: { ref: pr.headRefName ?? fallback.head?.ref ?? null, sha: fallback.head?.sha ?? null },
    base: { ref: pr.baseRefName ?? fallback.base?.ref ?? null, sha: fallback.base?.sha ?? null },
    headRefName: pr.headRefName ?? fallback.head?.ref ?? null,
    baseRefName: pr.baseRefName ?? fallback.base?.ref ?? null,
    updatedAt: pr.updatedAt ?? fallback.updated_at ?? null,
  };
}

export async function prReady(repo: string, token: string, number: number, dryRun: boolean): Promise<GitHubCommandResult> {
  const command = "pr ready";
  const { owner, name } = repoParts(repo);
  const current = await githubRequest<GitHubPullRequest>(token, "GET", `/repos/${owner}/${name}/pulls/${number}`);
  if (isGitHubError(current)) return commandError(command, repo, current, { number, phase: "fetch-pr" });

  const pullRequest = prCompactSummary(current);
  if (current.state !== "open") {
    return validationError(command, repo, "只有 open 状态的 PR 才能转为 ready for review", {
      number,
      phase: "validate-pr-state",
      currentState: current.state,
      pullRequest,
    });
  }
  if (typeof current.draft !== "boolean") {
    return commandError(command, repo, errorPayload("invalid-response", "GitHub REST PR 响应缺少 draft 布尔状态，无法安全判断是否需要写入"), {
      number,
      phase: "validate-pr-draft",
      pullRequest,
    });
  }
  if (current.draft !== true) {
    return {
      ok: true,
      command,
      repo,
      number,
      dryRun,
      planned: false,
      changed: false,
      action: "already-ready",
      changedFields: [],
      pullRequest,
      rest: true,
      graphQl: false,
    };
  }

  const request = mutationPlan();
  if (dryRun) {
    return {
      ok: true,
      command,
      repo,
      number,
      dryRun: true,
      planned: true,
      changed: false,
      action: "would-mark-ready",
      changedFields: ["draft"],
      pullRequest,
      request,
      rest: true,
      graphQl: false,
    };
  }

  if (typeof current.node_id !== "string" || current.node_id.length === 0) {
    return commandError(command, repo, errorPayload("invalid-response", "GitHub REST PR 响应缺少 markPullRequestReadyForReview 所需的 node_id"), {
      number,
      phase: "validate-pr-node-id",
      pullRequest,
    });
  }

  const mutation = `
    mutation MarkPullRequestReadyForReview($pullRequestId: ID!) {
      markPullRequestReadyForReview(input: { pullRequestId: $pullRequestId }) {
        pullRequest {
          id
          number
          title
          state
          isDraft
          url
          headRefName
          baseRefName
          updatedAt
        }
      }
    }
  `;
  const response = await githubGraphqlRequest<ReadyPullRequestMutation>(token, mutation, { pullRequestId: current.node_id });
  if (isGitHubError(response)) {
    return commandError(command, repo, response, {
      number,
      phase: "mark-ready",
      pullRequest,
      request,
    });
  }
  const ready = response.markPullRequestReadyForReview?.pullRequest;
  if (ready === null || ready === undefined || ready.isDraft !== false) {
    return commandError(command, repo, errorPayload("invalid-response", "GitHub GraphQL markPullRequestReadyForReview 响应未确认 isDraft=false", { details: response }), {
      number,
      phase: "verify-ready-response",
      pullRequest,
      request,
    });
  }

  return {
    ok: true,
    command,
    repo,
    number: ready.number ?? number,
    dryRun: false,
    planned: false,
    changed: true,
    action: "marked-ready",
    changedFields: ["draft"],
    pullRequest: readyPullRequestSummary(ready, current),
    request,
    rest: true,
    graphQl: true,
  };
}
