import type {
  BusinessPartnerQueries,
  ItemManagementQueries,
  OrganizationQueries,
  PrimitivesQueries,
} from "../module";

export type Company = NonNullable<
  Awaited<ReturnType<OrganizationQueries["getCompany"]>>["value"]["company"]
>;
export type Partner = NonNullable<
  Awaited<ReturnType<BusinessPartnerQueries["getPartner"]>>["value"]["partner"]
>;
export type PartnerRole = NonNullable<
  Awaited<ReturnType<BusinessPartnerQueries["getPartnerRole"]>>["value"]["partnerRole"]
>;
export type Currency = NonNullable<
  Awaited<ReturnType<PrimitivesQueries["getCurrency"]>>["value"]["currency"]
>;
export type Item = NonNullable<
  Awaited<ReturnType<ItemManagementQueries["getItem"]>>["value"]["item"]
>;

export const mockOrgQueries = (
  company: Company | null,
): Pick<OrganizationQueries, "getCompany"> => ({
  getCompany: () => Promise.resolve({ ok: true as const, value: { company } }),
});

export const mockBPQueries = (
  partner: Partner | null,
  partnerRole: PartnerRole | null,
): Pick<BusinessPartnerQueries, "getPartner" | "getPartnerRole"> => ({
  getPartner: () => Promise.resolve({ ok: true as const, value: { partner } }),
  getPartnerRole: () => Promise.resolve({ ok: true as const, value: { partnerRole } }),
});

export const mockPrimitivesQueries = (
  currency: Currency | null,
): Pick<PrimitivesQueries, "getCurrency"> => ({
  getCurrency: () => Promise.resolve({ ok: true as const, value: { currency } }),
});

// Item & Record<string, unknown>: requires a full Item row but permits off-model extras
// (companyId) that the command reads defensively.
export const mockItemQueries = (
  items: (Item & Record<string, unknown>)[],
): Pick<ItemManagementQueries, "getItem"> => ({
  getItem: (_db, input) =>
    Promise.resolve({
      ok: true as const,
      value: { item: "id" in input ? (items.find((item) => item.id === input.id) ?? null) : null },
    }),
});
