/**
 * robot-manager v3 demo seed
 *
 * 产出（manual 运行 / 不进默认 db:seed 链）：
 *   - 组织 TEST_ORG
 *   - platform_master 主数据：3 Customer / 2 Supplier / 2 Partner / 4 Location
 *   - robot_manager.RobotSystemConfig（FFSN 规则）
 *   - 3 RobotModel × 5 RobotSku
 *   - 30 RobotUnit 分布在各 v3 stage（自动建 Snapshot + LifecycleEvent 链）
 *   - 5 PurchaseOrder + 5 SalesOrder + 3 DeliveryRequest + 3 DeliveryFulfillment 示例
 *
 * 运行：
 *   cd backend
 *   npx dotenv -e .env -- npx ts-node prisma/seeds/robot-manager-v3-seed.ts
 */
import {
  PrismaClient,
  RobotLifecycleStage,
  RobotLifecycleEventType,
  RobotUsageType,
  CustomerType,
  SupplierType,
  PartnerRole,
  LocationType,
  PurchaseOrderStatus,
  SalesOrderStatus,
  SalesContractStatus,
  SalesLineType,
  DeliveryRequestType,
  DeliveryRequestStatus,
  PaymentDirection,
  PaymentStatus,
  PaymentMethod,
  PaymentRelatedType,
} from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  // 0. 取一个 user 当 createdById
  const itadmin = await prisma.user.findFirst({ where: { username: 'itadmin' } });
  if (!itadmin) throw new Error('itadmin 不存在，先跑 npm run init:itadmin');
  const userId = itadmin.id;

  // 1. 组织
  const org = await prisma.organization.upsert({
    where: { code: 'TEST_ORG' },
    create: { code: 'TEST_ORG', name: 'FF Test Organization' },
    update: {},
  });
  const orgId = org.id;
  console.log(`[seed-v3] organization: ${org.code} (${orgId})`);

  // 2. L1a 主数据
  const tesla = await prisma.customer.upsert({
    where: { code: 'CUST-TESLA' },
    create: {
      code: 'CUST-TESLA',
      name: 'Tesla, Inc.',
      type: CustomerType.B2B,
      industry: 'EV',
      countryCode: 'US',
      currencyCode: 'USD',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const spacex = await prisma.customer.upsert({
    where: { code: 'CUST-SPACEX' },
    create: {
      code: 'CUST-SPACEX',
      name: 'SpaceX',
      type: CustomerType.B2B,
      industry: 'Aerospace',
      countryCode: 'US',
      currencyCode: 'USD',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const boeing = await prisma.customer.upsert({
    where: { code: 'CUST-BOEING' },
    create: {
      code: 'CUST-BOEING',
      name: 'Boeing',
      type: CustomerType.B2B,
      industry: 'Aerospace',
      countryCode: 'US',
      currencyCode: 'USD',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });

  const agibot = await prisma.supplier.upsert({
    where: { code: 'SUPP-AGIBOT' },
    create: {
      code: 'SUPP-AGIBOT',
      name: 'AGIBOT Robotics',
      type: SupplierType.MANUFACTURER,
      countryCode: 'CN',
      currencyCode: 'CNY',
      paymentTerms: 'Net 30',
      leadTimeDays: 45,
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const deeprobotics = await prisma.supplier.upsert({
    where: { code: 'SUPP-DEEP' },
    create: {
      code: 'SUPP-DEEP',
      name: 'DeepRobotics',
      type: SupplierType.MANUFACTURER,
      countryCode: 'CN',
      currencyCode: 'CNY',
      paymentTerms: 'Net 45',
      leadTimeDays: 60,
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });

  await prisma.partner.upsert({
    where: { code: 'PART-MENTOR-A' },
    create: {
      code: 'PART-MENTOR-A',
      name: 'Mentor A',
      role: PartnerRole.MENTOR,
      countryCode: 'US',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  await prisma.partner.upsert({
    where: { code: 'PART-CUSTOMS-B' },
    create: {
      code: 'PART-CUSTOMS-B',
      name: 'Customs Broker B',
      role: PartnerRole.CUSTOMS_BROKER,
      countryCode: 'CN',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });

  const locHQ = await prisma.location.upsert({
    where: { code: 'LOC-HQ-FUZHOU' },
    create: {
      code: 'LOC-HQ-FUZHOU',
      name: 'FF HQ Fuzhou Warehouse',
      type: LocationType.WAREHOUSE,
      countryCode: 'CN',
      address: 'Fuzhou, Fujian Province',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const locW1 = await prisma.location.upsert({
    where: { code: 'LOC-W1-USA' },
    create: {
      code: 'LOC-W1-USA',
      name: 'W1 Warehouse - California',
      type: LocationType.WAREHOUSE,
      countryCode: 'US',
      address: 'Fremont, CA',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const locFTZ = await prisma.location.upsert({
    where: { code: 'LOC-FTZ-SH' },
    create: {
      code: 'LOC-FTZ-SH',
      name: 'Shanghai Free Trade Zone',
      type: LocationType.BONDED_ZONE,
      countryCode: 'CN',
      address: 'Shanghai FTZ',
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  const locTesla = await prisma.location.upsert({
    where: { code: 'LOC-TESLA-SH' },
    create: {
      code: 'LOC-TESLA-SH',
      name: 'Tesla Shanghai Factory',
      type: LocationType.CUSTOMER_SITE,
      countryCode: 'CN',
      address: 'Shanghai Gigafactory',
      customerId: tesla.id,
      organizationId: orgId,
      createdById: userId,
    },
    update: {},
  });
  console.log(
    `[seed-v3] platform_master: customers(3) suppliers(2) partners(2) locations(4)`,
  );

  // 3. RobotSystemConfig
  await prisma.robotSystemConfig.upsert({
    where: { key: 'ffsn_rule' },
    create: {
      key: 'ffsn_rule',
      value: { prefix: 'FF', dateFormat: 'YYYYMM', seqLength: 5, resetPeriod: 'MONTHLY' },
      description: 'FFSN 自动生成规则',
    },
    update: {},
  });

  // 4. Model + SKU（并发 upsert：彼此独立）
  const [aegis, rover, titan] = await Promise.all([
    prisma.robotModel.upsert({
      where: { code: 'AEGIS' },
      create: { code: 'AEGIS', name: 'Aegis 守护者', brand: 'FF', organizationId: orgId, createdById: userId },
      update: {},
    }),
    prisma.robotModel.upsert({
      where: { code: 'ROVER' },
      create: { code: 'ROVER', name: 'Rover 探索者', brand: 'FF', organizationId: orgId, createdById: userId },
      update: {},
    }),
    prisma.robotModel.upsert({
      where: { code: 'TITAN' },
      create: { code: 'TITAN', name: 'Titan 巨人', brand: 'FF', organizationId: orgId, createdById: userId },
      update: {},
    }),
  ]);

  const skuList = [
    { code: 'AEGIS-STD', name: 'Aegis Standard', modelId: aegis.id, defaultPrice: 35000, defaultCost: 22000, currencyCode: 'USD' },
    { code: 'AEGIS-PRO', name: 'Aegis Pro', modelId: aegis.id, defaultPrice: 48000, defaultCost: 30000, currencyCode: 'USD' },
    { code: 'ROVER-STD', name: 'Rover Standard', modelId: rover.id, defaultPrice: 28000, defaultCost: 18000, currencyCode: 'USD' },
    { code: 'ROVER-PRO', name: 'Rover Pro', modelId: rover.id, defaultPrice: 40000, defaultCost: 25000, currencyCode: 'USD' },
    { code: 'TITAN-STD', name: 'Titan Standard', modelId: titan.id, defaultPrice: 65000, defaultCost: 42000, currencyCode: 'USD' },
  ];
  const skus = await Promise.all(
    skuList.map((s) =>
      prisma.robotSku.upsert({
        where: { code: s.code },
        create: { ...s, organizationId: orgId, createdById: userId },
        update: {},
      }),
    ),
  );
  console.log(`[seed-v3] models(3) + skus(${skus.length})`);

  // 5. 1 个 PO + 1 个 SO 样本
  const po = await prisma.purchaseOrder.create({
    data: {
      poNo: `PO-${Date.now()}-001`,
      supplierId: agibot.id,
      currencyCode: 'CNY',
      totalAmount: 220000,
      status: PurchaseOrderStatus.ORDERED,
      orderedAt: new Date(),
      organizationId: orgId,
      createdById: userId,
      lines: {
        create: [
          {
            lineNo: 1,
            skuId: skus[0].id,
            quantity: 10,
            unitPrice: 22000,
            totalPrice: 220000,
            currencyCode: 'CNY',
            defaultUsageType: RobotUsageType.SALES,
          },
        ],
      },
    },
    include: { lines: true },
  });

  const so = await prisma.salesOrder.create({
    data: {
      soNo: `SO-${Date.now()}-001`,
      customerId: tesla.id,
      salesPersonId: userId,
      currencyCode: 'USD',
      totalAmount: 70000,
      contractStatus: SalesContractStatus.SIGNED,
      status: SalesOrderStatus.APPROVED,
      signedAt: new Date(),
      organizationId: orgId,
      createdById: userId,
      lines: {
        create: [
          {
            lineNo: 1,
            lineType: SalesLineType.HARDWARE,
            unitPrice: 35000,
            netAmount: 35000,
            currencyCode: 'USD',
          },
          {
            lineNo: 2,
            lineType: SalesLineType.SOFTWARE,
            unitPrice: 35000,
            netAmount: 35000,
            currencyCode: 'USD',
          },
        ],
      },
    },
  });

  // 6. 100 台 robot_units 分布在各 v3 stage（按原 30 台比例放大 ~3.33×）
  const distribution: Array<[RobotLifecycleStage, number]> = [
    [RobotLifecycleStage.SUPPLY_PO_CREATED, 13],
    [RobotLifecycleStage.SUPPLY_IN_PRODUCTION, 10],
    [RobotLifecycleStage.SUPPLY_READY_TO_SHIP, 7],
    [RobotLifecycleStage.LOGISTICS_IN_TRANSIT, 10],
    [RobotLifecycleStage.LOGISTICS_BONDED, 7],
    [RobotLifecycleStage.LOGISTICS_CUSTOMS_CLEARED, 3],
    [RobotLifecycleStage.WAREHOUSE_RECEIVED, 3],
    [RobotLifecycleStage.WAREHOUSE_AT_W1_PDI, 7],
    [RobotLifecycleStage.WAREHOUSE_MODIFICATION, 3],
    [RobotLifecycleStage.WAREHOUSE_AT_W2, 3],
    [RobotLifecycleStage.WAREHOUSE_BRANDED_READY, 14],
    [RobotLifecycleStage.SALES_RESERVED, 7],
    [RobotLifecycleStage.DELIVERY_READY, 4],
    [RobotLifecycleStage.DELIVERY_DELIVERED, 7],
    [RobotLifecycleStage.AFTERSALES_UNDER_REPAIR, 2],
  ];

  let seq = 100;
  // 批量 createMany：3 张表分别一次性插入，10-20× 快于逐条 await
  const { randomUUID } = await import('node:crypto');
  const now = new Date();
  const units: any[] = [];
  const events: any[] = [];
  const snapshots: any[] = [];
  for (const [stage, count] of distribution) {
    for (let i = 0; i < count; i++) {
      const sku = skus[seq % skus.length];
      const unitId = randomUUID();
      const eventId = randomUUID();
      units.push({
        id: unitId,
        ffsn: `FF-202605-${String(seq).padStart(5, '0')}`,
        organizationId: orgId,
        modelId: sku.modelId,
        skuId: sku.id,
        usageType: RobotUsageType.SALES,
        originalSupplierId: agibot.id,
        purchaseOrderId: po.id,
        purchaseOrderLineId: po.lines[0].id,
        createdById: userId,
      });
      events.push({
        id: eventId,
        robotUnitId: unitId,
        eventType: RobotLifecycleEventType.stage_changed,
        fromStage: null,
        toStage: stage,
        actorUserId: userId,
        notes: 'v3 demo seed',
        payload: {},
        occurredAt: now,
        organizationId: orgId,
        createdById: userId,
      });
      snapshots.push({
        robotUnitId: unitId,
        currentStage: stage,
        currentLocationId: stage.startsWith('WAREHOUSE_') ? locHQ.id : null,
        lastEventId: eventId,
        lastEventAt: now,
        version: 1,
      });
      seq++;
    }
  }
  await prisma.robotUnit.createMany({ data: units, skipDuplicates: true });
  await prisma.robotLifecycleEvent.createMany({ data: events, skipDuplicates: true });
  await prisma.robotUnitSnapshot.createMany({ data: snapshots, skipDuplicates: true });
  console.log(`[seed-v3] robot_units(${units.length}) + snapshots + first events`);
  console.log('✅ v3 demo seed done');
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(() => prisma.$disconnect());
