import "server-only";

import { prisma } from "@/lib/db";
import { parseProductContext } from "@/lib/types/product-context";
import { parseMatchTags } from "@/lib/types/product-match";
import {
  buildMergedProductContext,
  formatCatalogProductSummary,
  recommendProductFromCatalog,
  type CatalogBrand,
  type CatalogProduct,
} from "@/lib/types/product-catalog";

export type { CatalogBrand, CatalogProduct };
export { buildMergedProductContext, formatCatalogProductSummary, recommendProductFromCatalog };

export async function loadBrandCatalog(brandId: string): Promise<CatalogBrand | null> {
  const brand = await prisma.brandProfile.findUnique({
    where: { id: brandId },
    include: { products: { orderBy: { updatedAt: "desc" } } },
  });
  if (!brand) return null;

  return {
    id: brand.id,
    name: brand.name,
    notes: brand.notes,
    products: brand.products.map((p) => ({
      id: p.id,
      label: p.label,
      context: p.context,
      matchTags: parseMatchTags(p.matchTags),
    })),
  };
}

export async function resolveProductContextForPlacement(input: {
  brandProfileId?: string | null;
  productProfileId?: string | null;
  fallbackContext?: string | null;
  searchTag?: string | null;
}): Promise<string | null> {
  if (input.brandProfileId) {
    const catalog = await loadBrandCatalog(input.brandProfileId);
    if (catalog && catalog.products.length > 0) {
      const picked = recommendProductFromCatalog(catalog.products, {
        searchTag: input.searchTag,
        defaultProductId: input.productProfileId,
      });
      if (picked) {
        return buildMergedProductContext(catalog.name, picked.context, picked.label);
      }
    }
  }

  if (input.productProfileId) {
    const product = await prisma.productProfile.findUnique({
      where: { id: input.productProfileId },
      include: { brand: true },
    });
    if (product) {
      const brandName = product.brand?.name ?? parseProductContext(product.context).brand;
      return buildMergedProductContext(brandName, product.context, product.label);
    }
  }

  return input.fallbackContext?.trim() || null;
}

export async function syncTopicProductSnapshot(topicId: string) {
  const topic = await prisma.topic.findUnique({ where: { id: topicId } });
  if (!topic) return;

  const context = await resolveProductContextForPlacement({
    brandProfileId: topic.brandProfileId,
    productProfileId: topic.productProfileId,
    fallbackContext: topic.productContext,
  });

  await prisma.topic.update({
    where: { id: topicId },
    data: { productContext: context },
  });
}

export async function attachBrandToTopic(
  topicId: string,
  brandId: string | null,
  productId: string | null
) {
  if (!brandId) {
    return prisma.topic.update({
      where: { id: topicId },
      data: { brandProfileId: null, productProfileId: productId },
    });
  }

  const brand = await prisma.brandProfile.findUnique({
    where: { id: brandId },
    include: { products: true },
  });
  if (!brand) throw new Error("找不到品牌");

  if (productId) {
    const product = brand.products.find((p) => p.id === productId);
    if (!product) throw new Error("此品牌下找不到該產品");
  }

  const context = await resolveProductContextForPlacement({
    brandProfileId: brandId,
    productProfileId: productId,
  });

  return prisma.topic.update({
    where: { id: topicId },
    data: {
      brandProfileId: brandId,
      productProfileId: productId,
      productContext: context,
    },
  });
}

/** 將舊版扁平 ProductProfile 整理成品牌 + 產品結構。 */
export async function migrateLegacyProductCatalog(accountIds: string[]) {
  if (accountIds.length === 0) return;

  const orphans = await prisma.productProfile.findMany({
    where: { accountId: { in: accountIds }, brandId: null },
  });

  for (const row of orphans) {
    const fields = parseProductContext(row.context);
    const brandName = fields.brand?.trim() || row.label.split("·")[0]?.trim() || row.label;

    let brand = await prisma.brandProfile.findFirst({
      where: { accountId: row.accountId, name: brandName },
    });
    if (!brand) {
      brand = await prisma.brandProfile.create({
        data: {
          accountId: row.accountId ?? undefined,
          name: brandName,
        },
      });
    }

    await prisma.productProfile.update({
      where: { id: row.id },
      data: {
        brandId: brand.id,
        label: fields.product?.trim() || row.label,
        matchTags: row.matchTags,
      },
    });

    await prisma.topic.updateMany({
      where: { productProfileId: row.id, brandProfileId: null },
      data: { brandProfileId: brand.id },
    });
  }
}