import "server-only";

import { Query } from "node-appwrite";

import { DATABASE_ID, TABLES, type Job, type Patient } from "./schema";
import { createAdminClient } from "./server";
import { toPlain } from "./serialize";

export async function listPatients(
  clinicTenantId: string,
  options: { includeArchived?: boolean } = {},
): Promise<Patient[]> {
  const { tablesDB } = createAdminClient();
  const queries = [
    Query.equal("clinicTenantId", clinicTenantId),
    Query.orderDesc("$createdAt"),
    Query.limit(500),
  ];
  if (!options.includeArchived) {
    queries.push(Query.notEqual("archived", true));
  }
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.patients,
    queries,
  });
  return toPlain(result.rows as unknown as Patient[]);
}

export async function getPatient(
  patientId: string,
  clinicTenantId: string,
): Promise<Patient | null> {
  try {
    const { tablesDB } = createAdminClient();
    const row = (await tablesDB.getRow(
      DATABASE_ID,
      TABLES.patients,
      patientId,
    )) as unknown as Patient;
    if (row.clinicTenantId !== clinicTenantId) return null;
    return toPlain(row);
  } catch {
    return null;
  }
}

/**
 * Every job linked to this patient — by explicit patientId on newer jobs,
 * or by matching patientCode on legacy rows that pre-date the relation
 * (we still want to surface that history).
 */
export async function listPatientJobs(
  patientId: string,
  patientCode: string,
  clinicTenantId: string,
): Promise<Job[]> {
  const { tablesDB } = createAdminClient();
  const [byId, byCode] = await Promise.all([
    tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.jobs,
      queries: [
        Query.equal("clinicTenantId", clinicTenantId),
        Query.equal("patientId", patientId),
        Query.orderDesc("$createdAt"),
        Query.limit(200),
      ],
    }),
    tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.jobs,
      queries: [
        Query.equal("clinicTenantId", clinicTenantId),
        Query.equal("patientCode", patientCode),
        Query.orderDesc("$createdAt"),
        Query.limit(200),
      ],
    }),
  ]);
  const seen = new Set<string>();
  const merged: Job[] = [];
  for (const row of [...byId.rows, ...byCode.rows] as unknown as Job[]) {
    if (seen.has(row.$id)) continue;
    seen.add(row.$id);
    merged.push(row);
  }
  merged.sort((a, b) => (a.$createdAt < b.$createdAt ? 1 : -1));
  return toPlain(merged);
}
