import { verificarTokenVistaPrevia } from './preview-token';
import { envs } from 'src/config';
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { buildStoreConfig, StoreConfig } from '../ecommerce-config.mapper';
import { EcommerceNovedadesService } from '../novedades/ecommerce-novedades.service';

@Injectable()
export class EcommercePublicService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly novedadesService: EcommerceNovedadesService,
  ) {}

  /**
   * Resuelve el tenant y devuelve la configuración PUBLICADA.
   * - `preview=true`: devuelve el borrador actual (estado vigente del config),
   *   usado por el iframe de preview del panel.
   * - Pausada, en borrador o sin versión publicada: `status: 'closed'` con la
   *   marca del comercio, para que la tienda muestre un aviso en vez del catálogo.
   *
   * El identificador puede ser el subdominio ("empresa1") o el dominio propio
   * completo ("tienda.suempresa.com.py"): la tienda manda el host entero cuando
   * no cuelga del dominio raíz de Novasis. Acá sólo se buscaba por subdominio,
   * así que cualquier tienda con dominio propio recibía 404 y el front caía al
   * diseño estándar sin decir nada — se veía el template de demo en lugar de la
   * tienda del cliente.
   */
  async getPublicConfig(identificador: string, previewToken?: string): Promise<StoreConfig> {
    const config = await this.prisma.ecommerce_config.findFirst({
      where: { OR: [{ subdominio: identificador }, { dominio_custom: identificador }] },
    });

    if (!config) {
      throw new NotFoundException(`No existe una tienda para "${identificador}".`);
    }

    // El borrador sólo con un token de vista previa de esta misma empresa. Sin token
    // (o con `preview=true` a secas, como antes) se sirve lo publicado.
    const preview = verificarTokenVistaPrevia(previewToken, envs.jwtSecret) === config.empresa_id;

    // Preview: usar el estado actual (borrador) del config
    if (preview) {
      const novedades = await this.novedadesService.listActivas(config.empresa_id);
      return { ...buildStoreConfig(config, { status: 'draft' }), novedades };
    }

    const version = config.published_version_id
      ? await this.prisma.ecommerce_config_version.findUnique({
          where: { id: config.published_version_id },
        })
      : null;
    const snap = (version?.config_snapshot as Record<string, any> | undefined) ?? null;

    // Producción: usar la versión publicada congelada
    const fila = snap
      ? {
          subdominio: snap.subdominio ?? config.subdominio,
          nombre_comercial: snap.nombre_comercial,
          slogan: snap.slogan,
          logo_url: snap.logo_url,
          // El snapshot publicado omitía el favicon: la tienda en producción
          // se quedaba con el favicon del template. Fallback al config vivo
          // para snapshots viejos que no lo congelaron.
          favicon_url: snap.favicon_url ?? config.favicon_url,
          theme_config: snap.theme_config,
          layout_config: snap.layout_config,
          catalog_config: snap.catalog_config,
          promotion_slots: snap.promotion_slots,
          seasonal_templates: snap.seasonal_templates,
          checkout_config: snap.checkout_config,
          footer_config: snap.footer_config,
          content_pages_config: snap.content_pages_config,
        }
      : config;

    // Tienda pausada, en borrador o sin publicar: se responde 200 con `status: 'closed'`
    // y sólo la marca (nombre, logo, colores; el pie no, porque sin datos propios trae
    // los de contacto de la plantilla). Antes era un 404, y como el caché de
    // datos de Next no guarda respuestas que no son 200, la tienda seguía sirviendo la
    // última versión cacheada: pausar no la sacaba de línea. Y si el caché vencía,
    // caía al diseño de ejemplo de la plantilla en lugar de avisar que está en pausa.
    if (!snap || config.estado !== 'activa') {
      const base = buildStoreConfig(fila, { status: 'closed' });
      return {
        version: base.version,
        status: 'closed',
        closedReason: config.estado === 'pausada' ? 'pausada' : 'sin_publicar',
        source: 'tenant',
        identity: base.identity,
        theme: base.theme,
        typography: base.typography,
      };
    }

    const novedades = await this.novedadesService.listActivas(config.empresa_id);
    return { ...buildStoreConfig(fila, { status: 'published' }), novedades };
  }
}
