const { PrismaClient, RoleCode, TenantStatus, UserStatus, ChannelStatus, ConversationStatus, ConversationPriority, MessageDirection, MessageType, DeliveryStatus, OptInStatus, TemplateApprovalStatus, CampaignStatus, CampaignAudienceType, CampaignType, PaymentStatus } = require("@prisma/client");
const { pbkdf2Sync, randomBytes } = require("crypto");

const prisma = new PrismaClient();

function hashPassword(password) {
  const iterations = 120000;
  const salt = randomBytes(16);
  const digest = pbkdf2Sync(password, salt, iterations, 32, "sha256");

  return `pbkdf2$${iterations}$${salt.toString("base64url")}$${digest.toString("base64url")}`;
}

async function main() {
  await prisma.campaignRecipient.deleteMany();
  await prisma.broadcastCampaign.deleteMany();
  await prisma.messageTemplate.deleteMany();
  await prisma.segmentMember.deleteMany();
  await prisma.contactSegment.deleteMany();
  await prisma.conversationActivity.deleteMany();
  await prisma.conversationTag.deleteMany();
  await prisma.conversationNote.deleteMany();
  await prisma.message.deleteMany();
  await prisma.conversation.deleteMany();
  await prisma.contactTag.deleteMany();
  await prisma.tag.deleteMany();
  await prisma.contact.deleteMany();
  await prisma.webhookEvent.deleteMany();
  await prisma.auditLog.deleteMany();
  await prisma.usageMetric.deleteMany();
  await prisma.billingInvoice.deleteMany();
  await prisma.authToken.deleteMany();
  await prisma.channel.deleteMany();
  await prisma.user.deleteMany();
  await prisma.role.deleteMany();
  await prisma.tenant.deleteMany();
  await prisma.subscriptionPlan.deleteMany();

  await prisma.subscriptionPlan.createMany({
    data: [
      {
        id: "plan-basic",
        name: "Basic",
        code: "basic",
        priceMonthly: 1500000,
        messageQuota: 10000,
        seatQuota: 5,
        broadcastQuota: 2000,
        featuresJson: JSON.stringify({ inbox: true, contacts: true, analytics: "basic" })
      },
      {
        id: "plan-pro",
        name: "Pro",
        code: "pro",
        priceMonthly: 2500000,
        messageQuota: 50000,
        seatQuota: 15,
        broadcastQuota: 10000,
        featuresJson: JSON.stringify({ inbox: true, contacts: true, analytics: "extended", broadcast: true })
      }
    ]
  });

  await prisma.tenant.createMany({
    data: [
      {
        id: "tenant-acme",
        name: "Acme Co",
        slug: "acme-co",
        companyName: "Acme Co",
        timezone: "Asia/Jakarta",
        status: TenantStatus.ACTIVE,
        planId: "plan-pro"
      },
      {
        id: "tenant-sinar",
        name: "Sinar Abadi",
        slug: "sinar-abadi",
        companyName: "PT Sinar Abadi",
        timezone: "Asia/Jakarta",
        status: TenantStatus.TRIAL,
        planId: "plan-basic"
      }
    ]
  });

  await prisma.role.createMany({
    data: [
      { id: "role-super-admin", name: "Super Admin", code: RoleCode.SUPER_ADMIN, permissionsJson: JSON.stringify({ global: true }) },
      { id: "role-admin-acme", tenantId: "tenant-acme", name: "Admin Client", code: RoleCode.ADMIN_CLIENT, permissionsJson: JSON.stringify({ tenant: true }) },
      { id: "role-agent-acme", tenantId: "tenant-acme", name: "Agent", code: RoleCode.AGENT, permissionsJson: JSON.stringify({ inbox: true }) },
      { id: "role-admin-sinar", tenantId: "tenant-sinar", name: "Admin Client", code: RoleCode.ADMIN_CLIENT, permissionsJson: JSON.stringify({ tenant: true }) }
    ]
  });

  await prisma.user.createMany({
    data: [
      {
        id: "user-super-admin",
        tenantId: "tenant-acme",
        fullName: "Platform Owner",
        email: "owner@inboxsuite.test",
        passwordHash: hashPassword("demo123"),
        roleId: "role-super-admin",
        status: UserStatus.ACTIVE,
        lastLoginAt: new Date("2026-04-20T08:00:00Z")
      },
      {
        id: "user-admin-001",
        tenantId: "tenant-acme",
        fullName: "Admin Operations",
        email: "admin@acme.test",
        passwordHash: hashPassword("admin123"),
        roleId: "role-admin-acme",
        status: UserStatus.ACTIVE,
        lastLoginAt: new Date("2026-04-20T09:00:00Z")
      },
      {
        id: "user-agent-001",
        tenantId: "tenant-acme",
        fullName: "Farhan",
        email: "farhan@acme.test",
        passwordHash: hashPassword("agent123"),
        roleId: "role-agent-acme",
        status: UserStatus.ACTIVE,
        lastLoginAt: new Date("2026-04-20T09:12:00Z")
      },
      {
        id: "user-agent-002",
        tenantId: "tenant-acme",
        fullName: "Tiara",
        email: "tiara@acme.test",
        passwordHash: hashPassword("agent123"),
        roleId: "role-agent-acme",
        status: UserStatus.ACTIVE,
        lastLoginAt: new Date("2026-04-20T08:54:00Z")
      },
      {
        id: "user-admin-sinar",
        tenantId: "tenant-sinar",
        fullName: "Sinar Admin",
        email: "admin@sinar.test",
        passwordHash: hashPassword("sinar123"),
        roleId: "role-admin-sinar",
        status: UserStatus.INVITED
      }
    ]
  });

  await prisma.channel.createMany({
    data: [
      {
        id: "channel-main-acme",
        tenantId: "tenant-acme",
        channelName: "Main WA",
        provider: "Meta BSP",
        wabaId: "waba-acme-main",
        phoneNumberId: "phone-acme-main",
        displayPhoneNumber: "+628111111111",
        status: ChannelStatus.CONNECTED,
        webhookStatus: "healthy",
        lastSyncAt: new Date("2026-04-20T09:10:00Z")
      },
      {
        id: "channel-ops-acme",
        tenantId: "tenant-acme",
        channelName: "Ops WA",
        provider: "Meta BSP",
        wabaId: "waba-acme-ops",
        phoneNumberId: "phone-acme-ops",
        displayPhoneNumber: "+628222222222",
        status: ChannelStatus.CONNECTED,
        webhookStatus: "healthy",
        lastSyncAt: new Date("2026-04-20T08:45:00Z")
      },
      {
        id: "channel-sinar",
        tenantId: "tenant-sinar",
        channelName: "Sales WA",
        provider: "Meta BSP",
        wabaId: "waba-sinar-main",
        phoneNumberId: "phone-sinar-main",
        displayPhoneNumber: "+628333333333",
        status: ChannelStatus.PENDING,
        webhookStatus: "pending"
      }
    ]
  });

  await prisma.tag.createMany({
    data: [
      { id: "tag-enterprise", tenantId: "tenant-acme", name: "Enterprise", color: "#155eef" },
      { id: "tag-hot-lead", tenantId: "tenant-acme", name: "Hot Lead", color: "#ff7a00" },
      { id: "tag-payment", tenantId: "tenant-acme", name: "Payment Follow-up", color: "#b54708" },
      { id: "tag-b2b", tenantId: "tenant-acme", name: "B2B", color: "#067647" }
    ]
  });

  await prisma.contact.createMany({
    data: [
      {
        id: "contact-001",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        fullName: "Nadia Pratama",
        phoneNumber: "+628123456789",
        email: "nadia@example.com",
        countryCode: "ID",
        optInStatus: OptInStatus.OPTED_IN,
        lastInteractionAt: new Date("2026-04-20T09:12:00Z")
      },
      {
        id: "contact-002",
        tenantId: "tenant-acme",
        channelId: "channel-ops-acme",
        fullName: "PT Sinar Abadi",
        phoneNumber: "+62219876543",
        email: "ops@sinarabadi.co.id",
        countryCode: "ID",
        optInStatus: OptInStatus.UNKNOWN,
        lastInteractionAt: new Date("2026-04-19T11:00:00Z")
      },
      {
        id: "contact-003",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        fullName: "Rizky Saputra",
        phoneNumber: "+628777777777",
        email: "rizky@example.com",
        countryCode: "ID",
        optInStatus: OptInStatus.OPTED_IN,
        lastInteractionAt: new Date("2026-04-18T12:00:00Z")
      }
    ]
  });

  await prisma.contactTag.createMany({
    data: [
      { id: "ct-001", tenantId: "tenant-acme", contactId: "contact-001", tagId: "tag-enterprise" },
      { id: "ct-002", tenantId: "tenant-acme", contactId: "contact-001", tagId: "tag-hot-lead" },
      { id: "ct-003", tenantId: "tenant-acme", contactId: "contact-002", tagId: "tag-b2b" },
      { id: "ct-004", tenantId: "tenant-acme", contactId: "contact-003", tagId: "tag-payment" }
    ]
  });

  await prisma.contactSegment.create({
    data: {
      id: "segment-hot-leads",
      tenantId: "tenant-acme",
      name: "Hot Leads",
      description: "Enterprise prospects",
      rulesJson: JSON.stringify({ tags: ["Enterprise", "Hot Lead"] })
    }
  });

  await prisma.segmentMember.create({
    data: {
      id: "segment-member-001",
      tenantId: "tenant-acme",
      segmentId: "segment-hot-leads",
      contactId: "contact-001"
    }
  });

  await prisma.conversation.createMany({
    data: [
      {
        id: "conv-001",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        contactId: "contact-001",
        subject: "Enterprise pricing",
        status: ConversationStatus.OPEN,
        priority: ConversationPriority.HIGH,
        assignedUserId: "user-agent-001",
        firstMessageAt: new Date("2026-04-20T09:00:00Z"),
        lastMessageAt: new Date("2026-04-20T09:12:00Z"),
        lastInboundAt: new Date("2026-04-20T09:12:00Z")
      },
      {
        id: "conv-002",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        contactId: "contact-003",
        subject: "Payment follow-up",
        status: ConversationStatus.PENDING,
        priority: ConversationPriority.NORMAL,
        firstMessageAt: new Date("2026-04-20T08:30:00Z"),
        lastMessageAt: new Date("2026-04-20T08:47:00Z"),
        lastInboundAt: new Date("2026-04-20T08:47:00Z")
      },
      {
        id: "conv-003",
        tenantId: "tenant-acme",
        channelId: "channel-ops-acme",
        contactId: "contact-002",
        subject: "Template request",
        status: ConversationStatus.RESOLVED,
        priority: ConversationPriority.NORMAL,
        assignedUserId: "user-agent-002",
        firstMessageAt: new Date("2026-04-19T09:00:00Z"),
        lastMessageAt: new Date("2026-04-19T11:00:00Z"),
        lastInboundAt: new Date("2026-04-19T10:20:00Z"),
        lastOutboundAt: new Date("2026-04-19T11:00:00Z"),
        resolvedAt: new Date("2026-04-19T11:10:00Z")
      }
    ]
  });

  await prisma.conversationTag.createMany({
    data: [
      { id: "cvt-001", tenantId: "tenant-acme", conversationId: "conv-001", tagId: "tag-enterprise" },
      { id: "cvt-002", tenantId: "tenant-acme", conversationId: "conv-001", tagId: "tag-hot-lead" },
      { id: "cvt-003", tenantId: "tenant-acme", conversationId: "conv-002", tagId: "tag-payment" },
      { id: "cvt-004", tenantId: "tenant-acme", conversationId: "conv-003", tagId: "tag-b2b" }
    ]
  });

  await prisma.message.createMany({
    data: [
      {
        id: "msg-001",
        tenantId: "tenant-acme",
        conversationId: "conv-001",
        channelId: "channel-main-acme",
        contactId: "contact-001",
        direction: MessageDirection.INBOUND,
        type: MessageType.TEXT,
        contentText: "Halo, saya mau tanya soal paket enterprise untuk tim saya.",
        deliveryStatus: DeliveryStatus.READ,
        createdAt: new Date("2026-04-20T09:00:00Z"),
        readAt: new Date("2026-04-20T09:00:00Z")
      },
      {
        id: "msg-002",
        tenantId: "tenant-acme",
        conversationId: "conv-001",
        channelId: "channel-main-acme",
        direction: MessageDirection.OUTBOUND,
        type: MessageType.TEXT,
        contentText: "Tentu. Boleh saya tahu estimasi jumlah agent yang akan memakai sistem?",
        deliveryStatus: DeliveryStatus.DELIVERED,
        sentByUserId: "user-agent-001",
        createdAt: new Date("2026-04-20T09:05:00Z"),
        sentAt: new Date("2026-04-20T09:05:00Z"),
        deliveredAt: new Date("2026-04-20T09:05:05Z")
      },
      {
        id: "msg-003",
        tenantId: "tenant-acme",
        conversationId: "conv-002",
        channelId: "channel-main-acme",
        contactId: "contact-003",
        direction: MessageDirection.INBOUND,
        type: MessageType.TEXT,
        contentText: "Sudah saya transfer, mohon dicek ya.",
        deliveryStatus: DeliveryStatus.READ,
        createdAt: new Date("2026-04-20T08:47:00Z"),
        readAt: new Date("2026-04-20T08:47:00Z")
      }
    ]
  });

  await prisma.conversationNote.create({
    data: {
      id: "note-001",
      tenantId: "tenant-acme",
      conversationId: "conv-001",
      userId: "user-agent-001",
      content: "Prospek enterprise, follow-up sore ini."
    }
  });

  await prisma.conversationActivity.createMany({
    data: [
      {
        id: "act-001",
        tenantId: "tenant-acme",
        conversationId: "conv-001",
        actorUserId: "user-agent-001",
        activityType: "assigned",
        metadataJson: JSON.stringify({ assignee: "Farhan" })
      },
      {
        id: "act-002",
        tenantId: "tenant-acme",
        conversationId: "conv-001",
        actorUserId: "user-agent-001",
        activityType: "message_sent",
        metadataJson: JSON.stringify({ messageId: "msg-002" })
      }
    ]
  });

  await prisma.messageTemplate.createMany({
    data: [
      {
        id: "tpl-001",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        name: "promo_april_2026",
        category: "Marketing",
        languageCode: "id",
        templateType: "text",
        bodyText: "Halo {{1}}, ada promo spesial untuk bisnis Anda minggu ini.",
        approvalStatus: TemplateApprovalStatus.APPROVED
      },
      {
        id: "tpl-002",
        tenantId: "tenant-acme",
        channelId: "channel-ops-acme",
        name: "billing_reminder",
        category: "Utility",
        languageCode: "id",
        templateType: "text",
        bodyText: "Halo {{1}}, berikut pengingat pembayaran Anda.",
        approvalStatus: TemplateApprovalStatus.PENDING
      }
    ]
  });

  await prisma.broadcastCampaign.createMany({
    data: [
      {
        id: "campaign-001",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        templateId: "tpl-001",
        createdByUserId: "user-admin-001",
        name: "Promo April",
        campaignType: CampaignType.BROADCAST,
        audienceType: CampaignAudienceType.SEGMENT,
        segmentId: "segment-hot-leads",
        scheduledAt: new Date("2026-04-20T10:00:00Z"),
        startedAt: new Date("2026-04-20T10:00:00Z"),
        finishedAt: new Date("2026-04-20T10:30:00Z"),
        status: CampaignStatus.COMPLETED,
        totalRecipients: 1203,
        totalSent: 1203,
        totalDelivered: 1180,
        totalRead: 873,
        totalFailed: 23
      },
      {
        id: "campaign-002",
        tenantId: "tenant-acme",
        channelId: "channel-ops-acme",
        templateId: "tpl-002",
        createdByUserId: "user-admin-001",
        name: "Billing Reminder",
        campaignType: CampaignType.BULK_FOLLOWUP,
        audienceType: CampaignAudienceType.MANUAL,
        status: CampaignStatus.DRAFT,
        totalRecipients: 0
      }
    ]
  });

  await prisma.campaignRecipient.createMany({
    data: [
      {
        id: "recipient-001",
        tenantId: "tenant-acme",
        campaignId: "campaign-001",
        contactId: "contact-001",
        phoneNumber: "+628123456789",
        sendStatus: DeliveryStatus.DELIVERED,
        sentAt: new Date("2026-04-20T10:01:00Z"),
        deliveredAt: new Date("2026-04-20T10:01:05Z"),
        readAt: new Date("2026-04-20T11:00:00Z")
      },
      {
        id: "recipient-002",
        tenantId: "tenant-acme",
        campaignId: "campaign-001",
        contactId: "contact-003",
        phoneNumber: "+628777777777",
        sendStatus: DeliveryStatus.FAILED,
        failureReason: "Template mismatch"
      }
    ]
  });

  await prisma.usageMetric.createMany({
    data: [
      {
        id: "usage-001",
        tenantId: "tenant-acme",
        metricDate: new Date("2026-04-20T00:00:00Z"),
        inboundMessages: 128,
        outboundMessages: 96,
        activeContacts: 3,
        activeAgents: 2,
        broadcastSent: 1203,
        storageUsedMb: 512
      }
    ]
  });

  await prisma.billingInvoice.createMany({
    data: [
      {
        id: "invoice-001",
        tenantId: "tenant-acme",
        planId: "plan-pro",
        invoiceNumber: "INV-2026-001",
        periodStart: new Date("2026-04-01T00:00:00Z"),
        periodEnd: new Date("2026-04-30T23:59:59Z"),
        subtotal: 2500000,
        taxAmount: 275000,
        totalAmount: 2775000,
        paymentStatus: PaymentStatus.PAID,
        dueDate: new Date("2026-04-30T00:00:00Z"),
        paidAt: new Date("2026-04-15T00:00:00Z")
      },
      {
        id: "invoice-002",
        tenantId: "tenant-sinar",
        planId: "plan-basic",
        invoiceNumber: "INV-2026-002",
        periodStart: new Date("2026-04-01T00:00:00Z"),
        periodEnd: new Date("2026-04-30T23:59:59Z"),
        subtotal: 1500000,
        taxAmount: 165000,
        totalAmount: 1665000,
        paymentStatus: PaymentStatus.UNPAID,
        dueDate: new Date("2026-05-01T00:00:00Z")
      }
    ]
  });

  await prisma.auditLog.createMany({
    data: [
      {
        id: "audit-001",
        tenantId: "tenant-acme",
        actorUserId: "user-agent-001",
        entityType: "conversation",
        entityId: "conv-001",
        action: "message_sent",
        metadataJson: JSON.stringify({ messageId: "msg-002" })
      },
      {
        id: "audit-002",
        tenantId: "tenant-acme",
        actorUserId: "user-admin-001",
        entityType: "campaign",
        entityId: "campaign-001",
        action: "campaign_created",
        metadataJson: JSON.stringify({ recipients: 1203 })
      }
    ]
  });

  await prisma.webhookEvent.createMany({
    data: [
      {
        id: "webhook-001",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        eventType: "message.inbound",
        providerEventId: "evt_001",
        payloadJson: JSON.stringify({ source: "meta", conversationId: "conv-001" }),
        processStatus: "processed",
        processedAt: new Date("2026-04-20T09:00:02Z")
      },
      {
        id: "webhook-002",
        tenantId: "tenant-acme",
        channelId: "channel-main-acme",
        eventType: "message.status",
        providerEventId: "evt_002",
        payloadJson: JSON.stringify({ source: "meta", campaignId: "campaign-001" }),
        processStatus: "failed",
        failedReason: "Temporary provider mismatch"
      }
    ]
  });
}

main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (error) => {
    console.error(error);
    await prisma.$disconnect();
    process.exit(1);
  });
