import "server-only";

import { Query } from "node-appwrite";

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

export type JobCounterpart = {
  tenantId: string;
  companyName: string;
  kind: TenantKind;
};

export type JobWithCounterpart = Job & {
  counterpart: JobCounterpart | null;
};

async function fetchTenants(tenantIds: string[]): Promise<Map<string, JobCounterpart>> {
  if (tenantIds.length === 0) return new Map();
  const { tablesDB } = createAdminClient();
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.tenantSettings,
    queries: [Query.equal("tenantId", tenantIds), Query.limit(200)],
  });
  const map = new Map<string, JobCounterpart>();
  for (const row of result.rows as unknown as TenantSettings[]) {
    map.set(row.tenantId, {
      tenantId: row.tenantId,
      companyName: row.companyName,
      kind: row.kind,
    });
  }
  return map;
}

function enrichJob(j: Job, counterpartId: string, map: Map<string, JobCounterpart>): JobWithCounterpart {
  return { ...j, counterpart: map.get(counterpartId) ?? null };
}

/** Inbound for a lab tenant — jobs the lab has received. */
export async function listInboundJobs(labTenantId: string): Promise<JobWithCounterpart[]> {
  const { tablesDB } = createAdminClient();
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.jobs,
    queries: [
      Query.equal("labTenantId", labTenantId),
      Query.orderDesc("$createdAt"),
      Query.limit(200),
    ],
  });
  const jobs = result.rows as unknown as Job[];
  const map = await fetchTenants(Array.from(new Set(jobs.map((j) => j.clinicTenantId))));
  return toPlain(jobs.map((j) => enrichJob(j, j.clinicTenantId, map)));
}

/** Outbound for a clinic tenant — jobs the clinic has sent. */
export async function listOutboundJobs(clinicTenantId: string): Promise<JobWithCounterpart[]> {
  const { tablesDB } = createAdminClient();
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.jobs,
    queries: [
      Query.equal("clinicTenantId", clinicTenantId),
      Query.orderDesc("$createdAt"),
      Query.limit(200),
    ],
  });
  const jobs = result.rows as unknown as Job[];
  const map = await fetchTenants(Array.from(new Set(jobs.map((j) => j.labTenantId))));
  return toPlain(jobs.map((j) => enrichJob(j, j.labTenantId, map)));
}

/** For clinic's "Yeni İş Yayınla" form: list approved labs they can send to. */
export async function listApprovedLabsForClinic(
  clinicTenantId: string,
): Promise<JobCounterpart[]> {
  const { tablesDB } = createAdminClient();
  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.connections,
    queries: [
      Query.equal("clinicTenantId", clinicTenantId),
      Query.equal("status", "approved"),
      Query.limit(100),
    ],
  });
  const labIds = (result.rows as unknown as { labTenantId: string }[]).map(
    (r) => r.labTenantId,
  );
  const map = await fetchTenants(labIds);
  return toPlain(
    labIds
      .map((id) => map.get(id))
      .filter((v): v is JobCounterpart => Boolean(v)),
  );
}
