/**
 * resolvePax8CompanyMatch — the two-table transactional write behind
 * POST /api/pax8/company-matches/[id]/resolve.
 *
 * Both `pax8_companies.match_method='manual'` and
 * `pax8_company_match_review.resolved_at` must be set in the same
 * transaction, or pax8-company-matcher.ts's re-scoring eligibility guard
 * (lines ~216-231: `c.match_method IS DISTINCT FROM 'manual' AND NOT EXISTS
 * (... resolved_at IS NOT NULL)`) will re-flag the company on the next sync.
 *
 * Deliberately does NOT check candidate-list membership — D-05 (manual-search
 * fallback) and D-09 (zero-candidate case) require accepting a companyId that
 * was never one of the stored candidates, as long as it exists and is active.
 */

export type ResolveResult =
  | { ok: true; resolvedToCompanyId: number }
  | { ok: false; code: 'not_found' | 'already_resolved' | 'company_not_found'; message: string };

interface TxLike {
  query: <T = unknown>(sql: string, params?: unknown[]) => Promise<{ rows: T[]; rowCount: number }>;
}

interface ResolveParams {
  reviewId: string;
  companyId: number;
  note: string | null;
  userId: string | null;
}

interface ReviewRow {
  pax8_company_id: string;
  resolved_at: string | null;
}

export async function resolvePax8CompanyMatch(
  tx: TxLike,
  params: ResolveParams
): Promise<ResolveResult> {
  const { reviewId, companyId, note, userId } = params;

  const reviewRes = await tx.query<ReviewRow>(
    `SELECT pax8_company_id, resolved_at
       FROM pax8_company_match_review
      WHERE id = $1
      FOR UPDATE`,
    [reviewId]
  );
  if (reviewRes.rowCount === 0) {
    return { ok: false, code: 'not_found', message: 'Review not found' };
  }
  const review = reviewRes.rows[0];
  if (review.resolved_at) {
    return { ok: false, code: 'already_resolved', message: 'Already resolved' };
  }

  const companyRes = await tx.query(
    `SELECT 1 FROM companies WHERE id = $1 AND is_active = true AND is_deleted = false`,
    [companyId]
  );
  if (companyRes.rowCount === 0) {
    return { ok: false, code: 'company_not_found', message: 'Target company not found or inactive' };
  }

  await tx.query(
    `UPDATE pax8_companies
        SET autotask_company_id = $2,
            match_confidence     = NULL,
            match_method         = 'manual',
            matched_at           = NOW()
      WHERE id = $1`,
    [review.pax8_company_id, companyId]
  );

  await tx.query(
    `UPDATE pax8_company_match_review
        SET resolved_at          = NOW(),
            resolved_by_user_id  = $2,
            resolved_to_company_id = $3,
            resolution_note      = $4
      WHERE id = $1`,
    [reviewId, userId, companyId, note]
  );

  return { ok: true, resolvedToCompanyId: companyId };
}
