/**
 * POST /list-prs endpoint - List GitHub pull requests for a project
 */

import type { Request, Response } from 'express';
import { execAsync, execEnv, getErrorMessage, logError } from './common.js';
import { checkGitHubRemote } from './check-github-remote.js';

const OPEN_PRS_LIMIT = 100;
const MERGED_PRS_LIMIT = 50;
const PR_LIST_FIELDS =
  'number,title,state,author,createdAt,labels,url,isDraft,headRefName,reviewDecision,mergeable,body';
const PR_STATE_OPEN = 'open';
const PR_STATE_MERGED = 'merged';
const GH_PR_LIST_COMMAND = 'gh pr list';
const GH_STATE_FLAG = '--state';
const GH_JSON_FLAG = '--json';
const GH_LIMIT_FLAG = '--limit';

export interface GitHubLabel {
  name: string;
  color: string;
}

export interface GitHubAuthor {
  login: string;
}

export interface GitHubPR {
  number: number;
  title: string;
  state: string;
  author: GitHubAuthor;
  createdAt: string;
  labels: GitHubLabel[];
  url: string;
  isDraft: boolean;
  headRefName: string;
  reviewDecision: string | null;
  mergeable: string;
  body: string;
}

export interface ListPRsResult {
  success: boolean;
  openPRs?: GitHubPR[];
  mergedPRs?: GitHubPR[];
  error?: string;
}

export function createListPRsHandler() {
  return async (req: Request, res: Response): Promise<void> => {
    try {
      const { projectPath } = req.body;

      if (!projectPath) {
        res.status(400).json({ success: false, error: 'projectPath is required' });
        return;
      }

      // First check if this is a GitHub repo
      const remoteStatus = await checkGitHubRemote(projectPath);
      if (!remoteStatus.hasGitHubRemote) {
        res.status(400).json({
          success: false,
          error: 'Project does not have a GitHub remote',
        });
        return;
      }

      const repoQualifier =
        remoteStatus.owner && remoteStatus.repo ? `${remoteStatus.owner}/${remoteStatus.repo}` : '';
      const repoFlag = repoQualifier ? `-R ${repoQualifier}` : '';

      const [openResult, mergedResult] = await Promise.all([
        execAsync(
          [
            GH_PR_LIST_COMMAND,
            repoFlag,
            `${GH_STATE_FLAG} ${PR_STATE_OPEN}`,
            `${GH_JSON_FLAG} ${PR_LIST_FIELDS}`,
            `${GH_LIMIT_FLAG} ${OPEN_PRS_LIMIT}`,
          ]
            .filter(Boolean)
            .join(' '),
          {
            cwd: projectPath,
            env: execEnv,
          }
        ),
        execAsync(
          [
            GH_PR_LIST_COMMAND,
            repoFlag,
            `${GH_STATE_FLAG} ${PR_STATE_MERGED}`,
            `${GH_JSON_FLAG} ${PR_LIST_FIELDS}`,
            `${GH_LIMIT_FLAG} ${MERGED_PRS_LIMIT}`,
          ]
            .filter(Boolean)
            .join(' '),
          {
            cwd: projectPath,
            env: execEnv,
          }
        ),
      ]);
      const { stdout: openStdout } = openResult;
      const { stdout: mergedStdout } = mergedResult;

      const openPRs: GitHubPR[] = JSON.parse(openStdout || '[]');
      const mergedPRs: GitHubPR[] = JSON.parse(mergedStdout || '[]');

      res.json({
        success: true,
        openPRs,
        mergedPRs,
      });
    } catch (error) {
      logError(error, 'List GitHub PRs failed');
      res.status(500).json({ success: false, error: getErrorMessage(error) });
    }
  };
}
