import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getActiveAccountId } from "@/lib/account-context";
import { authErrorResponse } from "@/lib/auth/api";
import { isAccountInUserScope, requireUserAccountScope } from "@/lib/auth/user-scope";
import { migrateLegacyProductCatalog } from "@/lib/services/product-catalog";
import { parseMatchTags, serializeMatchTags } from "@/lib/types/product-match";
import { hasProductContext } from "@/lib/types/product-context";

function mapBrand(row: {
  id: string;
  name: string;
  notes: string | null;
  products: Array<{
    id: string;
    label: string;
    context: string;
    matchTags: string | null;
  }>;
  _count?: { products: number };
}) {
  return {
    id: row.id,
    name: row.name,
    notes: row.notes,
    products: row.products.map((p) => ({
      id: p.id,
      label: p.label,
      context: p.context,
      matchTags: parseMatchTags(p.matchTags),
    })),
    productCount: row._count?.products ?? row.products.length,
  };
}

function parsePositiveInt(value: string | null, fallback: number, max: number) {
  const parsed = Number.parseInt(value ?? "", 10);
  if (!Number.isFinite(parsed) || parsed < 1) return fallback;
  return Math.min(parsed, max);
}

export async function GET(request: Request) {
  try {
    const accountId = await getActiveAccountId();
    const { where: accountWhere, accountIds } = await requireUserAccountScope(accountId);
    try {
      await migrateLegacyProductCatalog(accountIds);
    } catch (migrateErr) {
      console.error("[brands] migrateLegacyProductCatalog failed:", migrateErr);
    }

    const { searchParams } = new URL(request.url);
    const brandId = searchParams.get("brandId");
    const fetchAll = searchParams.get("all") === "1";
    const q = searchParams.get("q")?.trim() ?? "";
    const page = parsePositiveInt(searchParams.get("page"), 1, 10_000);
    const limit = fetchAll
      ? 500
      : parsePositiveInt(searchParams.get("limit"), 8, 50);
    const productLimit = parsePositiveInt(searchParams.get("productLimit"), 12, 200);

    const searchWhere = q
      ? {
          OR: [
            { name: { contains: q } },
            { notes: { contains: q } },
            {
              products: {
                some: {
                  OR: [{ label: { contains: q } }, { matchTags: { contains: q } }],
                },
              },
            },
          ],
        }
      : {};

    const where = { ...accountWhere, ...searchWhere };

    if (brandId) {
      const brand = await prisma.brandProfile.findFirst({
        where: { ...where, id: brandId },
        include: {
          products: { orderBy: { updatedAt: "desc" }, take: productLimit },
          _count: { select: { products: true } },
        },
      });
      if (!brand) {
        return NextResponse.json({ error: "找不到品牌" }, { status: 404 });
      }
      return NextResponse.json({
        brand: mapBrand(brand),
        brands: [mapBrand(brand)],
        total: 1,
        page: 1,
        limit: 1,
        totalPages: 1,
      });
    }

    const total = await prisma.brandProfile.count({ where });
    const brands = await prisma.brandProfile.findMany({
      where,
      include: {
        products: { orderBy: { updatedAt: "desc" }, take: productLimit },
        _count: { select: { products: true } },
      },
      orderBy: { updatedAt: "desc" },
      ...(fetchAll ? {} : { skip: (page - 1) * limit, take: limit }),
    });

    const totalPages = fetchAll ? 1 : Math.max(1, Math.ceil(total / limit));

    return NextResponse.json({
      brands: brands.map(mapBrand),
      total,
      page: fetchAll ? 1 : page,
      limit: fetchAll ? total : limit,
      totalPages,
    });
  } catch (error) {
    const authRes = authErrorResponse(error);
    if (authRes) return authRes;
    const message = error instanceof Error ? error.message : "讀取品牌失敗";
    return NextResponse.json({ error: message, brands: [] }, { status: 500 });
  }
}

export async function POST(request: Request) {
  try {
    const { name, notes, product } = (await request.json()) as {
      name?: string;
      notes?: string;
      product?: {
        label?: string;
        context?: string;
        matchTags?: string[];
      };
    };

    if (!name?.trim()) {
      return NextResponse.json({ error: "請填寫品牌名稱" }, { status: 400 });
    }

    const accountId = await getActiveAccountId();
    if (!accountId) {
      return NextResponse.json({ error: "請先建立並選定經營帳號" }, { status: 400 });
    }

    const brand = await prisma.brandProfile.create({
      data: {
        accountId,
        name: name.trim(),
        notes: notes?.trim() || null,
        ...(product?.label && product.context && hasProductContext(product.context)
          ? {
              products: {
                create: {
                  accountId,
                  label: product.label.trim(),
                  context: product.context.trim(),
                  matchTags: serializeMatchTags(product.matchTags ?? []),
                },
              },
            }
          : {}),
      },
      include: { products: true },
    });

    return NextResponse.json({ brand: mapBrand(brand) });
  } catch (error) {
    const authRes = authErrorResponse(error);
    if (authRes) return authRes;
    const message = error instanceof Error ? error.message : "建立品牌失敗";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}

export async function PATCH(request: Request) {
  try {
    const { id, name, notes } = (await request.json()) as {
      id?: string;
      name?: string;
      notes?: string | null;
    };

    if (!id) return NextResponse.json({ error: "缺少 id" }, { status: 400 });

    const { accountIds } = await requireUserAccountScope(await getActiveAccountId());
    const existing = await prisma.brandProfile.findUnique({ where: { id } });
    if (!existing || !isAccountInUserScope(accountIds, existing.accountId)) {
      return NextResponse.json({ error: "找不到品牌" }, { status: 404 });
    }

    const brand = await prisma.brandProfile.update({
      where: { id },
      data: {
        ...(name !== undefined && { name: name.trim() }),
        ...(notes !== undefined && { notes: notes?.trim() || null }),
      },
      include: { products: { orderBy: { updatedAt: "desc" } } },
    });

    return NextResponse.json({ brand: mapBrand(brand) });
  } catch (error) {
    const authRes = authErrorResponse(error);
    if (authRes) return authRes;
    const message = error instanceof Error ? error.message : "更新品牌失敗";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}

export async function DELETE(request: Request) {
  try {
    const id = new URL(request.url).searchParams.get("id");
    if (!id) return NextResponse.json({ error: "缺少 id" }, { status: 400 });

    const { accountIds } = await requireUserAccountScope(await getActiveAccountId());
    const existing = await prisma.brandProfile.findUnique({ where: { id } });
    if (!existing || !isAccountInUserScope(accountIds, existing.accountId)) {
      return NextResponse.json({ error: "找不到品牌" }, { status: 404 });
    }

    const linkedTopics = await prisma.topic.count({ where: { brandProfileId: id } });
    if (linkedTopics > 0) {
      return NextResponse.json(
        { error: `仍有 ${linkedTopics} 個主題使用此品牌，請先更換` },
        { status: 400 }
      );
    }

    await prisma.brandProfile.delete({ where: { id } });
    return NextResponse.json({ success: true });
  } catch (error) {
    const authRes = authErrorResponse(error);
    if (authRes) return authRes;
    const message = error instanceof Error ? error.message : "刪除品牌失敗";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}