import { isPlainObject } from "es-toolkit";

import type { ExpectationResult, KeyedExpectations, ValueExpectation } from "../../expect/types";

import { mismatchFailure } from "../../expect/failure";
import { checkKeyedExpectations } from "../../expect/keyed";
import { checkValueExpectation } from "../../expect/value";

export function checkRowCount(actual: number, matcher: ValueExpectation): ExpectationResult {
  return checkValueExpectation(actual, matcher, {
    message: `rowCount ${actual} 不满足条件`,
    path: "rowCount",
    phase: "rowCount",
  });
}

export function checkRows(rows: unknown, rules: KeyedExpectations[]): ExpectationResult {
  if (!Array.isArray(rows)) {
    return {
      failure: mismatchFailure("row", "rows", rules, rows, "查询结果不是数组"),
      matched: false,
    };
  }

  for (let i = 0; i < rules.length; i++) {
    const rule = rules[i]!;
    if (i >= rows.length) {
      return {
        failure: mismatchFailure("row", `rows[${i}]`, "expected row", undefined, `结果行数不足，需要第 ${i + 1} 行`),
        matched: false,
      };
    }

    const row = rows[i]! as null | Record<string, unknown> | undefined;
    if (!isPlainObject(row)) {
      return {
        failure: mismatchFailure("row", `rows[${i}]`, "object", row, `第 ${i + 1} 行不是对象`),
        matched: false,
      };
    }

    const result = checkKeyedExpectations(row, rule, { path: `rows[${i}]`, phase: "row" });
    if (!result.matched) return result;
  }

  return { failure: null, matched: true };
}
