import { env } from "@/lib/runtime-env";
import { ensureSchema } from "./ensure-schema";

const profiles: Record<string, { depth: number; sides: number; rateCents: number }> = {
  TF15S: { depth: 15, sides: 1, rateCents: 8200 },
  TF30S: { depth: 30, sides: 1, rateCents: 10500 },
  TF45S: { depth: 45, sides: 1, rateCents: 12800 },
  TF60D: { depth: 60, sides: 2, rateCents: 18500 },
  TF75S: { depth: 75, sides: 1, rateCents: 26500 },
  TF80D: { depth: 80, sides: 2, rateCents: 35500 },
  TF100S: { depth: 100, sides: 1, rateCents: 31000 },
  TF120D: { depth: 120, sides: 2, rateCents: 42000 },
  TFBOX: { depth: 100, sides: 4, rateCents: 46500 },
};

let seeded: Promise<void> | null = null;

export async function ensureTextilePricingProfiles() {
  await ensureSchema();
  seeded ??= env.DB.batch(Object.entries(profiles).map(([code, profile]) =>
    env.DB.prepare(`INSERT OR IGNORE INTO textile_pricing_profiles
      (code, rate_per_m2_cents, base_price_cents, professional_discount_bp, enabled, version, updated_at)
      VALUES (?, ?, 16000, 1800, 1, 1, ?)`).bind(code, profile.rateCents, Date.now()),
  )).then(() => undefined);
  await seeded;
}

export async function calculateTextilePrice(input: {
  profileCode: string; widthCm: number; heightCm: number; quantity: number; isProfessional: boolean;
}) {
  await ensureTextilePricingProfiles();
  const geometry = profiles[input.profileCode];
  const row = await env.DB.prepare(`SELECT rate_per_m2_cents, base_price_cents, professional_discount_bp, enabled, version
    FROM textile_pricing_profiles WHERE code = ?`).bind(input.profileCode).first<{
      rate_per_m2_cents: number; base_price_cents: number; professional_discount_bp: number; enabled: number; version: number;
    }>();
  if (!geometry || !row || !row.enabled) throw new Error("Profil indisponible");

  const areaM2 = input.widthCm / 100 * input.heightCm / 100;
  const perimeterM = (input.widthCm + input.heightCm) * 2 / 100;
  const printRateCents = geometry.sides > 1 ? 6800 : 3800;
  const unitAmountCents = Math.max(row.base_price_cents,
    areaM2 * (row.rate_per_m2_cents + printRateCents) + perimeterM * geometry.depth * 55);
  const quantityDiscountBp = input.quantity >= 10 ? 9000 : input.quantity >= 5 ? 9500 : 10000;
  const professionalBp = input.isProfessional ? 10000 - row.professional_discount_bp : 10000;
  const amountCents = unitAmountCents * input.quantity * quantityDiscountBp / 10000 * professionalBp / 10000;

  return {
    amountCents: Math.round(amountCents / 100) * 100,
    unitAmountCents: Math.round(unitAmountCents / 100) * 100,
    areaM2,
    version: row.version,
    ratePerM2Cents: row.rate_per_m2_cents,
    professionalDiscountPercent: row.professional_discount_bp / 100,
    quantityDiscountPercent: (10000 - quantityDiscountBp) / 100,
  };
}
