'use server';

import { and, eq } from 'drizzle-orm';
import { revalidatePath } from 'next/cache';
import { db } from '@/db';
import { catalogItems, pricingConfig, tenants } from '@/db/schema';
import { getTenantId, type EnvioMode } from '@/db/pricing-queries';
import { parseCatalogCsv } from '@/budget/csv';

// Valida un importe en euros del formulario y lo convierte a céntimos.
// Lanza un error en español si el valor no es un número finito >= 0.
function eurosToCents(raw: FormDataEntryValue | null, campo: string): number {
  const euros = Number(raw);
  if (!Number.isFinite(euros) || euros < 0) {
    throw new Error(`El valor de "${campo}" debe ser un número mayor o igual que 0.`);
  }
  return Math.round(euros * 100);
}

function parsePositive(raw: FormDataEntryValue | null, campo: string): number {
  const n = Number(raw);
  if (!Number.isFinite(n) || n <= 0) {
    throw new Error(`El valor de "${campo}" debe ser un número mayor que 0.`);
  }
  return n;
}

export async function crearMaterial(formData: FormData) {
  const tenantId = await getTenantId();
  await db.insert(catalogItems).values({
    tenantId,
    categoria: formData.get('categoria') as 'suelo' | 'pared' | 'pintura' | 'mobiliario',
    nombre: String(formData.get('nombre') ?? ''),
    calidad: formData.get('calidad') as 'basica' | 'media' | 'premium',
    precioUnit: eurosToCents(formData.get('precioEuros'), 'precio'),
    unidad: formData.get('unidad') as 'm2' | 'ml' | 'ud',
    descriptorRender: String(formData.get('descriptorRender') ?? ''),
    esDefault: formData.get('esDefault') === 'on',
    sku: String(formData.get('sku') ?? ''),
  });
  revalidatePath('/panel/precios');
}

export async function actualizarPrecio(formData: FormData) {
  const tenantId = await getTenantId();
  const id = String(formData.get('id') ?? '');
  await db
    .update(catalogItems)
    .set({ precioUnit: eurosToCents(formData.get('precioEuros'), 'precio') })
    .where(and(eq(catalogItems.id, id), eq(catalogItems.tenantId, tenantId)));
  revalidatePath('/panel/precios');
}

export async function borrarMaterial(formData: FormData) {
  const tenantId = await getTenantId();
  const id = String(formData.get('id') ?? '');
  await db.delete(catalogItems).where(and(eq(catalogItems.id, id), eq(catalogItems.tenantId, tenantId)));
  revalidatePath('/panel/precios');
}

export async function actualizarConfig(formData: FormData) {
  const tenantId = await getTenantId();
  await db
    .update(pricingConfig)
    .set({
      alturaTechoDefault: parsePositive(formData.get('alturaTechoDefault'), 'altura de techo'),
      manoObra: {
        demolicion: eurosToCents(formData.get('mo_demolicion'), 'demolición'),
        impermeabilizacion: eurosToCents(formData.get('mo_impermeabilizacion'), 'impermeabilización'),
        fontaneria: eurosToCents(formData.get('mo_fontaneria'), 'fontanería'),
        electricidad: eurosToCents(formData.get('mo_electricidad'), 'electricidad'),
        mano_de_obra: eurosToCents(formData.get('mo_mano_de_obra'), 'mano de obra'),
      },
      updatedAt: new Date(),
    })
    .where(eq(pricingConfig.tenantId, tenantId));
  revalidatePath('/panel/precios');
}

export async function actualizarExtras(formData: FormData) {
  const tenantId = await getTenantId();
  await db
    .update(pricingConfig)
    .set({
      extras: {
        tuberias: eurosToCents(formData.get('extra_tuberias'), 'renovación de tuberías'),
        boletin: eurosToCents(formData.get('extra_boletin'), 'boletín eléctrico'),
        distribucion: eurosToCents(formData.get('extra_distribucion'), 'cambio de distribución'),
      },
      updatedAt: new Date(),
    })
    .where(eq(pricingConfig.tenantId, tenantId));
  revalidatePath('/panel/precios');
}

export async function actualizarEnvio(formData: FormData) {
  const tenantId = await getTenantId();
  const modo = formData.get('modo');
  if (modo !== 'automatico' && modo !== 'revision') {
    throw new Error('Modo de envío no válido.');
  }
  await db
    .update(tenants)
    .set({ envioPresupuesto: modo as EnvioMode })
    .where(eq(tenants.id, tenantId));
  revalidatePath('/panel/precios');
}

export type ImportResult = { ok: boolean; inserted: number; errors: { line: number; message: string }[] };

export async function importarCatalogoCsv(_prev: ImportResult | null, formData: FormData): Promise<ImportResult> {
  const tenantId = await getTenantId();
  const csv = String(formData.get('csv') ?? '');
  const { rows, errors } = parseCatalogCsv(csv);
  if (errors.length > 0) return { ok: false, inserted: 0, errors };

  for (const r of rows) {
    await db
      .insert(catalogItems)
      .values({ tenantId, ...r })
      .onConflictDoUpdate({
        target: [catalogItems.tenantId, catalogItems.sku],
        set: {
          categoria: r.categoria,
          nombre: r.nombre,
          calidad: r.calidad,
          precioUnit: r.precioUnit,
          unidad: r.unidad,
          descriptorRender: r.descriptorRender,
        },
      });
  }
  revalidatePath('/panel/precios');
  return { ok: true, inserted: rows.length, errors: [] };
}
