import { prisma } from "@/lib/prisma";
import type { MarkupConfig } from "@prisma/client";
import { listAllCustomerIds } from "@/modules/auth/service-token";
import type { ParsedMarkupInput } from "@/modules/pricing/markup-validation";

export type MarkupConfigDto = {
  customer_id: string;
  markup_type: "percent" | "fixed";
  markup_percent: number;
  markup_fixed_amount: number | null;
  operator_id: string;
  remark: string | null;
  updated_at: string;
};

export function serializeMarkupConfig(config: MarkupConfig): MarkupConfigDto {
  return {
    customer_id: config.customerId,
    markup_type: config.markupType === "fixed" ? "fixed" : "percent",
    markup_percent: Number(config.markupPercent),
    markup_fixed_amount:
      config.markupFixedAmount === null || config.markupFixedAmount === undefined
        ? null
        : Number(config.markupFixedAmount),
    operator_id: config.operatorId,
    remark: config.remark,
    updated_at: config.updatedAt.toISOString(),
  };
}

export function defaultMarkupDto(customerId: string): MarkupConfigDto {
  return {
    customer_id: customerId,
    markup_type: "percent",
    markup_percent: 0,
    markup_fixed_amount: null,
    operator_id: "",
    remark: null,
    updated_at: new Date(0).toISOString(),
  };
}

export async function upsertMarkupConfig(
  customerId: string,
  input: ParsedMarkupInput,
  operatorId: string,
  remark: string | null,
): Promise<MarkupConfigDto> {
  const config = await prisma.markupConfig.upsert({
    where: { customerId },
    create: {
      customerId,
      markupType: input.markupType,
      markupPercent: input.markupPercent,
      markupFixedAmount: input.markupFixedAmount,
      operatorId,
      remark,
    },
    update: {
      markupType: input.markupType,
      markupPercent: input.markupPercent,
      markupFixedAmount: input.markupFixedAmount,
      operatorId,
      remark,
      isDeleted: false,
    },
  });

  return serializeMarkupConfig(config);
}

export async function listAdminMarkupConfigs(options: {
  page: number;
  size: number;
  keyword?: string;
}): Promise<{ list: MarkupConfigDto[]; total: number; page: number; size: number }> {
  const keyword = options.keyword?.trim().toLowerCase() ?? "";
  const customerIds = (await listAllCustomerIds()).filter((id) =>
    keyword ? id.toLowerCase().includes(keyword) : true,
  );

  const configs = await prisma.markupConfig.findMany({
    where: { customerId: { in: customerIds }, isDeleted: false },
  });
  const configMap = new Map(configs.map((c) => [c.customerId, c]));

  const merged = customerIds.map((customerId) => {
    const existing = configMap.get(customerId);
    return existing ? serializeMarkupConfig(existing) : defaultMarkupDto(customerId);
  });

  const total = merged.length;
  const start = (options.page - 1) * options.size;
  const list = merged.slice(start, start + options.size);

  return {
    list,
    total,
    page: options.page,
    size: options.size,
  };
}
