import { Test } from '@nestjs/testing';
import { Prisma } from '@prisma/client';
import { PublicService } from './public.service';
import { PrismaService } from '../prisma/prisma.service';
import { FamilyRecomputeService } from '../product-families/family-recompute.service';

/**
 * 三期灰度族块集成测试：PUBLIC_DETAIL_FROM_FAMILY 开关两态行为、
 * 族块字段内容、Good.familyId 派生与成员移动联动。
 */
describe('PublicService family block (PUBLIC_DETAIL_FROM_FAMILY)', () => {
  let service: PublicService;
  let prisma: PrismaService;
  const stamp = Date.now();
  const createdOriginGoodIds: bigint[] = [];
  const createdFamilyIds: bigint[] = [];
  const createdGoodIds: bigint[] = [];
  const createdCountryIds: bigint[] = [];
  const createdCategoryIds: bigint[] = [];
  const prevFlag = process.env.PUBLIC_DETAIL_FROM_FAMILY;
  let sdsGoodId = '';
  let familyId = 0n;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [PublicService, PrismaService],
    }).compile();
    service = moduleRef.get(PublicService);
    prisma = moduleRef.get(PrismaService);
    await prisma.onModuleInit();

    const country = await prisma.country.create({
      data: { countryName: `公开族国家-${stamp}` },
    });
    createdCountryIds.push(country.id);
    const category = await prisma.category.create({
      data: { categoryName: `公开族分类-${stamp}` },
    });
    createdCategoryIds.push(category.id);

    // 族 + 主链接（带变体）+ Good
    const og = await prisma.originGood.create({
      data: {
        sdsGoodId: `pubfam-${stamp}`,
        goodName: `美国（包邮）测试T恤-PF${stamp}-单面印花`,
        goodPrice: new Prisma.Decimal(25),
        craftLabel: '单面印花',
        logisticsLabel: '包邮',
      },
    });
    sdsGoodId = og.sdsGoodId;
    createdOriginGoodIds.push(og.id);
    await prisma.originGoodVariant.create({
      data: {
        originGoodId: og.id,
        sdsVariantId: 'pf-v1',
        sku: `PF-${stamp}-S`,
        sizeId: 'size_S',
        sizeName: 'S',
        colorId: 'color_blk',
        colorName: '黑色',
        price: new Prisma.Decimal(25),
      },
    });
    const family = await prisma.productFamily.create({
      data: { familyName: `公开族-${stamp}`, familyCode: `PF${stamp}`, primaryOriginGoodId: og.id },
    });
    familyId = family.id;
    createdFamilyIds.push(family.id);
    await prisma.originGood.update({ where: { id: og.id }, data: { familyId: family.id } });
    await new FamilyRecomputeService(prisma).recomputeFamily(family.id);

    const good = await prisma.good.create({
      data: {
        originGoodId: og.id,
        familyId: family.id,
        countryId: country.id,
        categoryId: category.id,
        goodName: `公开族商品-${stamp}`,
      },
    });
    createdGoodIds.push(good.id);
  });

  afterAll(async () => {
    process.env.PUBLIC_DETAIL_FROM_FAMILY = prevFlag;
    await prisma.good.deleteMany({ where: { id: { in: createdGoodIds } } });
    await prisma.originGood.deleteMany({ where: { id: { in: createdOriginGoodIds } } });
    await prisma.productFamily.deleteMany({ where: { id: { in: createdFamilyIds } } });
    await prisma.country.deleteMany({ where: { id: { in: createdCountryIds } } });
    await prisma.category.deleteMany({ where: { id: { in: createdCategoryIds } } });
    await prisma.$disconnect();
  });

  it('默认（未设开关）：输出族块', async () => {
    delete process.env.PUBLIC_DETAIL_FROM_FAMILY
    const detail = await service.getGood(sdsGoodId);
    expect(detail.goodId).toBe(sdsGoodId);
    expect(detail.family).toBeTruthy();
    expect(detail.family!.familyCode).toBe(`PF${stamp}`);
    expect(detail.family!.minPrice).toBe('25');
    // 旧字段保留（向后兼容）
    expect(detail.variants.length).toBe(1);
  });

  it('显式关闭（false）：响应完全不含 family 键（应急回退）', async () => {
    process.env.PUBLIC_DETAIL_FROM_FAMILY = 'false';
    const detail = await service.getGood(sdsGoodId);
    expect(detail.goodId).toBe(sdsGoodId);
    expect('family' in detail).toBe(false);
  });

  it('族变体并集：任何族成员链接的 sdsGoodId 均命中同一商品且变体含全体成员', async () => {
    process.env.PUBLIC_DETAIL_FROM_FAMILY = 'true';
    // 再加一个同族成员（不同仓库段）
    const og2 = await prisma.originGood.create({
      data: {
        sdsGoodId: `pubfam-m-${stamp}`,
        goodName: `美国（包邮）测试T恤-PF${stamp}-单面印花-二仓`,
        craftLabel: '单面印花',
        logisticsLabel: '包邮',
        familyId,
      },
    });
    createdOriginGoodIds.push(og2.id);
    await prisma.originGoodVariant.create({
      data: {
        originGoodId: og2.id,
        sdsVariantId: 'pf-m-v1',
        sku: `PF-${stamp}-M`,
        sizeId: 'size_M',
        sizeName: 'M',
        colorId: 'color_blk',
        colorName: '黑色',
        price: new Prisma.Decimal(26),
      },
    });

    // 用成员链接（非主链接）的 sdsGoodId 访问 → 命中同一商品（响应 goodId 仍为主链接）
    const detail = await service.getGood(`pubfam-m-${stamp}`);
    expect(detail.goodId).toBe(sdsGoodId);
    const skus = detail.variants.map((v) => v.sku);
    expect(skus).toContain(`PF-${stamp}-S`);
    expect(skus).toContain(`PF-${stamp}-M`); // 族成员变体并集
    // 清理：把成员移出族避免影响其他用例
    await prisma.originGoodVariant.deleteMany({ where: { originGoodId: og2.id } });
    await prisma.originGood.update({ where: { id: og2.id }, data: { familyId: null } });
  });

  it('无族商品：开关开启也不含 family 键', async () => {
    process.env.PUBLIC_DETAIL_FROM_FAMILY = 'true';
    const og2 = await prisma.originGood.create({
      data: {
        sdsGoodId: `pubfam-2-${stamp}`,
        goodName: `无族链接-${stamp}`,
        goodPrice: new Prisma.Decimal(10),
      },
    });
    createdOriginGoodIds.push(og2.id);
    const good2 = await prisma.good.create({
      data: {
        originGoodId: og2.id,
        countryId: createdCountryIds[0],
        categoryId: createdCategoryIds[0],
        goodName: `无族商品-${stamp}`,
      },
    });
    createdGoodIds.push(good2.id);
    const detail = await service.getGood(`pubfam-2-${stamp}`);
    expect('family' in detail).toBe(false);
  });
});

describe('Good familyId derivation', () => {
  let prisma: PrismaService;
  let familiesService: import('../product-families/product-families.service').ProductFamiliesService;
  const stamp = Date.now();
  const ids = { originGood: [] as bigint[], family: [] as bigint[], good: [] as bigint[], country: [] as bigint[], category: [] as bigint[] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [PrismaService],
    }).compile();
    prisma = moduleRef.get(PrismaService);
    await prisma.onModuleInit();
    familiesService = new (require('../product-families/product-families.service').ProductFamiliesService)(
      prisma,
      new FamilyRecomputeService(prisma),
    );
  });

  afterAll(async () => {
    await prisma.good.deleteMany({ where: { id: { in: ids.good } } });
    await prisma.originGood.deleteMany({ where: { id: { in: ids.originGood } } });
    await prisma.productFamily.deleteMany({ where: { id: { in: ids.family } } });
    await prisma.country.deleteMany({ where: { id: { in: ids.country } } });
    await prisma.category.deleteMany({ where: { id: { in: ids.category } } });
    await prisma.$disconnect();
  });

  it('updateMembers 移除/添加成员时，Good.familyId 联动', async () => {
    const country = await prisma.country.create({ data: { countryName: `联动国家-${stamp}` } });
    ids.country.push(country.id);
    const category = await prisma.category.create({ data: { categoryName: `联动分类-${stamp}` } });
    ids.category.push(category.id);
    const og = await prisma.originGood.create({
      data: { sdsGoodId: `derive-${stamp}`, goodName: `联动链接-${stamp}` },
    });
    ids.originGood.push(og.id);
    const family = await prisma.productFamily.create({
      data: { familyName: `联动族-${stamp}`, primaryOriginGoodId: og.id },
    });
    ids.family.push(family.id);
    await prisma.originGood.update({ where: { id: og.id }, data: { familyId: family.id } });
    const good = await prisma.good.create({
      data: {
        originGoodId: og.id,
        familyId: family.id,
        countryId: country.id,
        categoryId: category.id,
        goodName: `联动商品-${stamp}`,
      },
    });
    ids.good.push(good.id);

    // 移出族 → Good.familyId 置空
    await familiesService.updateMembers(family.id, { removeOriginGoodIds: [og.id.toString()] });
    expect(
      (await prisma.good.findUniqueOrThrow({ where: { id: good.id } })).familyId,
    ).toBeNull();

    // 重新挂回 → Good.familyId 回填
    await familiesService.updateMembers(family.id, { addOriginGoodIds: [og.id.toString()] });
    expect(
      (await prisma.good.findUniqueOrThrow({ where: { id: good.id } })).familyId,
    ).toBe(family.id);
  });
});
