'use server';

import { and, eq, ne } from 'drizzle-orm';
import { revalidatePath } from 'next/cache';
import { db } from '@/db';
import { tenants } from '@/db/schema';
import { getCurrentTenantId as getTenantId } from '@/lib/auth/current-user';
import { validarSlug } from '@/lib/validation/signup';
import { THEME_PRESETS, isHexColor, type ThemePresetId } from '@/lib/funnel/themes';

const LOGO_MAX_BYTES = 500_000;
const LOGO_TIPOS = ['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml'];
const ABOUT_FOTO_MAX_BYTES = 1_500_000;
const ABOUT_FOTO_TIPOS = ['image/png', 'image/jpeg', 'image/webp'];

function limpiar(raw: FormDataEntryValue | null): string | null {
  const s = String(raw ?? '').trim();
  return s.length > 0 ? s : null;
}

export async function actualizarEmpresa(formData: FormData) {
  const tenantId = await getTenantId();
  const nombreEmpresa = limpiar(formData.get('nombreEmpresa'));
  if (!nombreEmpresa) {
    throw new Error('El nombre de la empresa es obligatorio.');
  }

  const slugRaw = limpiar(formData.get('slug'));
  if (!slugRaw) {
    throw new Error('El enlace de tu funnel es obligatorio.');
  }
  const validacion = validarSlug(slugRaw);
  if (!validacion.ok) {
    throw new Error(validacion.error);
  }
  const slug = validacion.slug;

  // El slug es único en todo el sistema; comprobamos que no lo use otro reformista.
  const [colision] = await db
    .select({ id: tenants.id })
    .from(tenants)
    .where(and(eq(tenants.slug, slug), ne(tenants.id, tenantId)))
    .limit(1);
  if (colision) {
    throw new Error('Ese enlace ya está en uso. Elige otro.');
  }

  const aniosRaw = Number(formData.get('aniosExperiencia'));
  const aniosExperiencia =
    Number.isInteger(aniosRaw) && aniosRaw > 0 && aniosRaw <= 100 ? aniosRaw : null;

  await db
    .update(tenants)
    .set({
      nombreEmpresa,
      slug,
      cif: limpiar(formData.get('cif')),
      direccion: limpiar(formData.get('direccion')),
      provincia: limpiar(formData.get('provincia')),
      telefono: limpiar(formData.get('telefono')),
      email: limpiar(formData.get('email')),
      web: limpiar(formData.get('web')),
      seoTitle: limpiar(formData.get('seoTitle')),
      seoDescription: limpiar(formData.get('seoDescription')),
      aboutEnabled: formData.get('aboutEnabled') === 'on',
      aboutTexto: limpiar(formData.get('aboutTexto')),
      aniosExperiencia,
    })
    .where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
  revalidatePath('/panel');
}

export type LogoResult = { ok: boolean; error?: string };

export async function subirLogo(_prev: LogoResult | null, formData: FormData): Promise<LogoResult> {
  const tenantId = await getTenantId();
  const file = formData.get('logo');
  if (!(file instanceof File) || file.size === 0) {
    return { ok: false, error: 'Selecciona un archivo de imagen.' };
  }
  if (!LOGO_TIPOS.includes(file.type)) {
    return { ok: false, error: 'Formato no válido. Usa PNG, JPG, WEBP o SVG.' };
  }
  if (file.size > LOGO_MAX_BYTES) {
    return { ok: false, error: 'El logo no puede superar los 500 KB.' };
  }
  const base64 = Buffer.from(await file.arrayBuffer()).toString('base64');
  const dataUri = `data:${file.type};base64,${base64}`;
  await db.update(tenants).set({ logoUrl: dataUri }).where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
  revalidatePath('/panel');
  return { ok: true };
}

export async function quitarLogo() {
  const tenantId = await getTenantId();
  await db.update(tenants).set({ logoUrl: null }).where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
  revalidatePath('/panel');
}

export async function subirAboutFoto(
  _prev: LogoResult | null,
  formData: FormData
): Promise<LogoResult> {
  const tenantId = await getTenantId();
  const file = formData.get('aboutFoto');
  if (!(file instanceof File) || file.size === 0) {
    return { ok: false, error: 'Selecciona un archivo de imagen.' };
  }
  if (!ABOUT_FOTO_TIPOS.includes(file.type)) {
    return { ok: false, error: 'Formato no válido. Usa PNG, JPG o WEBP.' };
  }
  if (file.size > ABOUT_FOTO_MAX_BYTES) {
    return { ok: false, error: 'La foto no puede superar los 1,5 MB.' };
  }
  const base64 = Buffer.from(await file.arrayBuffer()).toString('base64');
  const dataUri = `data:${file.type};base64,${base64}`;
  await db.update(tenants).set({ aboutFotoUrl: dataUri }).where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
  return { ok: true };
}

export async function quitarAboutFoto() {
  const tenantId = await getTenantId();
  await db.update(tenants).set({ aboutFotoUrl: null }).where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
}

// Guarda el tema de la landing del reformista: preset + color personalizado opcional.
export async function guardarTema(
  _prev: LogoResult | null,
  formData: FormData
): Promise<LogoResult> {
  const tenantId = await getTenantId();
  const presetRaw = String(formData.get('themePreset') ?? '');
  const themePreset: ThemePresetId = presetRaw in THEME_PRESETS ? (presetRaw as ThemePresetId) : 'pizarra';

  const usarColor = formData.get('usarColor') === 'on';
  const colorRaw = String(formData.get('themeColor') ?? '').trim();
  const themeColor = usarColor && isHexColor(colorRaw) ? colorRaw : null;

  await db
    .update(tenants)
    .set({ themePreset, themeColor })
    .where(eq(tenants.id, tenantId));
  revalidatePath('/panel/empresa');
  return { ok: true };
}
