import { PrismaClient } from '@prisma/client'
import bcrypt from 'bcryptjs'

const prisma = new PrismaClient()

async function main() {
  console.log('🌱 Starting database seeding...')

  // Create currencies
  console.log('📈 Creating currencies...')
  const ugxCurrency = await prisma.currency.upsert({
    where: { code: 'UGX' },
    update: {},
    create: {
      code: 'UGX',
      name: 'Ugandan Shilling',
      symbol: 'UGX',
      isActive: true,
    },
  })

  const usdCurrency = await prisma.currency.upsert({
    where: { code: 'USD' },
    update: {},
    create: {
      code: 'USD',
      name: 'US Dollar',
      symbol: '$',
      isActive: true,
    },
  })

  // Create companies
  console.log('🏢 Creating companies...')
  const company1 = await prisma.company.upsert({
    where: { email: 'admin@propmaster.io' },
    update: {},
    create: {
      name: 'PropMaster Property Management',
      email: 'admin@propmaster.io',
      phone: '+256701234567',
      address: 'Plot 123, Kampala Road, Nakasero, Kampala',
      bankName: 'Centenary Bank',
      bankAccountNumber: '1234567890',
      bankAccountName: 'PropMaster Ltd',
      commissionRate: 10.0,
      rentDueDay: 1,
      baseCurrency: 'UGX',
      usdToUgxRate: 3700.0,
      subscriptionStatus: 'active',
    },
  })

  const company2 = await prisma.company.upsert({
    where: { email: 'info@southendproperties.com' },
    update: {},
    create: {
      name: 'South End Properties',
      email: 'info@southendproperties.com',
      phone: '+256702345678',
      address: 'Plot 456, Jinja Road, Bugolobi, Kampala',
      bankName: 'Stanbic Bank',
      bankAccountNumber: '0987654321',
      bankAccountName: 'South End Properties Ltd',
      commissionRate: 8.5,
      rentDueDay: 5,
      baseCurrency: 'UGX',
      usdToUgxRate: 3700.0,
      subscriptionStatus: 'active',
    },
  })

  // Create users (company admins and owners)
  console.log('👥 Creating users...')
  const hashedPassword = await bcrypt.hash('password123', 10)

  const admin1 = await prisma.user.upsert({
    where: { email: 'admin@propmaster.io' },
    update: {},
    create: {
      email: 'admin@propmaster.io',
      passwordHash: hashedPassword,
      firstName: 'John',
      lastName: 'Admin',
      phone: '+256701234567',
      role: 'company_admin',
      companyId: company1.id,
      emailVerified: true,
      timezone: 'Africa/Kampala',
    },
  })

  const admin2 = await prisma.user.upsert({
    where: { email: 'admin@southendproperties.com' },
    update: {},
    create: {
      email: 'admin@southendproperties.com',
      passwordHash: hashedPassword,
      firstName: 'Sarah',
      lastName: 'Manager',
      phone: '+256702345678',
      role: 'company_admin',
      companyId: company2.id,
      emailVerified: true,
      timezone: 'Africa/Kampala',
    },
  })

  const owner1 = await prisma.user.upsert({
    where: { email: 'owner1@propmaster.io' },
    update: {},
    create: {
      email: 'owner1@propmaster.io',
      passwordHash: hashedPassword,
      firstName: 'Michael',
      lastName: 'Property',
      phone: '+256703456789',
      role: 'owner',
      companyId: company1.id,
      commissionRate: 10.0,
      commissionDueDay: 1,
      emailVerified: true,
      timezone: 'Africa/Kampala',
    },
  })

  const owner2 = await prisma.user.upsert({
    where: { email: 'owner2@propmaster.io' },
    update: {},
    create: {
      email: 'owner2@propmaster.io',
      passwordHash: hashedPassword,
      firstName: 'Grace',
      lastName: 'Landlord',
      phone: '+256704567890',
      role: 'owner',
      companyId: company1.id,
      commissionRate: 10.0,
      commissionDueDay: 1,
      emailVerified: true,
      timezone: 'Africa/Kampala',
    },
  })

  // Create estates
  console.log('🏘️ Creating estates...')
  const estate1 = await prisma.estate.create({
    data: {
      companyId: company1.id,
      name: 'Kampala Central Estate',
      description: 'Prime residential and commercial properties in central Kampala',
      location: 'Central Kampala',
      streetAddress: 'Plot 123, Kampala Road',
      city: 'Kampala',
      district: 'Kampala',
      region: 'Central',
      totalProperties: 5,
      totalUnits: 25,
      amenities: JSON.stringify(['24/7 Security', 'Parking', 'Generator', 'Water Supply']),
    },
  })

  const estate2 = await prisma.estate.create({
    data: {
      companyId: company1.id,
      name: 'Bugolobi Heights',
      description: 'Modern apartments in the upscale Bugolobi neighborhood',
      location: 'Bugolobi',
      streetAddress: 'Plot 456, Jinja Road',
      city: 'Kampala',
      district: 'Kampala',
      region: 'Central',
      totalProperties: 3,
      totalUnits: 18,
      amenities: JSON.stringify(['Gym', 'Swimming Pool', 'Parking', 'Elevator']),
    },
  })

  // Create properties
  console.log('🏠 Creating properties...')
  const property1 = await prisma.property.create({
    data: {
      companyId: company1.id,
      estateId: estate1.id,
      ownerId: owner1.id,
      name: 'Sunrise Apartment Building',
      description: 'Modern 5-floor apartment building with 10 units',
      propertyType: 'apartment_building',
      propertyLocation: 'Plot 123, Kampala Road, Nakasero',
      purchasePrice: 500000000, // 500M UGX
      currentMarketValue: 600000000, // 600M UGX
      totalUnits: 10,
      totalFloors: 5,
      yearBuilt: 2018,
      status: 'active',
      amenities: JSON.stringify(['Parking', 'Security', 'Water', 'Electricity']),
    },
  })

  const property2 = await prisma.property.create({
    data: {
      companyId: company1.id,
      estateId: estate1.id,
      ownerId: owner2.id,
      name: 'Nakasero Plaza',
      description: 'Commercial building with retail spaces and offices',
      propertyType: 'commercial',
      propertyLocation: 'Plot 124, Kampala Road, Nakasero',
      purchasePrice: 800000000, // 800M UGX
      currentMarketValue: 900000000, // 900M UGX
      totalUnits: 15,
      totalFloors: 4,
      yearBuilt: 2020,
      status: 'active',
      amenities: JSON.stringify(['Parking', 'Security', 'Elevator', 'Backup Generator']),
    },
  })

  const property3 = await prisma.property.create({
    data: {
      companyId: company1.id,
      estateId: estate2.id,
      ownerId: owner1.id,
      name: 'Bugolobi Gardens',
      description: 'Luxury apartments with garden views',
      propertyType: 'apartment_building',
      propertyLocation: 'Plot 456, Jinja Road, Bugolobi',
      purchasePrice: 700000000, // 700M UGX
      currentMarketValue: 750000000, // 750M UGX
      totalUnits: 8,
      totalFloors: 3,
      yearBuilt: 2019,
      status: 'active',
      amenities: JSON.stringify(['Garden', 'Parking', 'Security', 'Gym']),
    },
  })

  // Create units
  console.log('🏢 Creating units...')
  const units = []
  for (let i = 1; i <= 10; i++) {
    const unit = await prisma.unit.create({
      data: {
        companyId: company1.id,
        propertyId: property1.id,
        unitNumber: `A${i}`,
        name: `Apartment A${i}`,
        unitType: i <= 2 ? 'studio' : i <= 6 ? '1_bedroom' : '2_bedroom',
        bedrooms: i <= 2 ? 0 : i <= 6 ? 1 : 2,
        bathrooms: i <= 2 ? 1 : i <= 6 ? 1 : 2,
        squareFeet: i <= 2 ? 400 : i <= 6 ? 600 : 800,
        floorNumber: Math.ceil(i / 2),
        monthlyRent: i <= 2 ? 800000 : i <= 6 ? 1200000 : 1500000, // UGX
        securityDeposit: i <= 2 ? 800000 : i <= 6 ? 1200000 : 1500000,
        status: i <= 8 ? 'occupied' : 'available',
        maxOccupants: i <= 2 ? 2 : i <= 6 ? 3 : 4,
        amenities: JSON.stringify(['Kitchen', 'Bathroom', 'Balcony']),
      },
    })
    units.push(unit)
  }

  // Create tenants
  console.log('👨‍👩‍👧‍👦 Creating tenants...')
  const tenant1 = await prisma.tenant.create({
    data: {
      companyId: company1.id,
      unitId: units[0].id,
      firstName: 'Richard',
      lastName: 'Miyingo',
      email: 'richardmiyingo@gmail.com',
      phone: '+256701234567',
      passwordHash: hashedPassword,
      nationalId: 'CM123456789ABC',
      emergencyContactName: 'Jane Miyingo',
      emergencyContactPhone: '+256702345678',
      leaseStartDate: new Date('2024-01-01'),
      leaseEndDate: new Date('2025-12-31'),
      monthlyRent: 800000,
      securityDeposit: 800000,
      rentDueDay: 1,
      status: 'active',
      moveInDate: new Date('2024-01-01'),
      isPrimaryTenant: true,
      notes: 'Excellent tenant, pays on time',
    },
  })

  const tenant2 = await prisma.tenant.create({
    data: {
      companyId: company1.id,
      unitId: units[1].id,
      firstName: 'Ronald',
      lastName: 'Nyanzi',
      email: 'ronald.nyanzi@email.com',
      phone: '+256702345678',
      passwordHash: hashedPassword,
      nationalId: 'CM234567890BCD',
      emergencyContactName: 'Mary Nyanzi',
      emergencyContactPhone: '+256703456789',
      leaseStartDate: new Date('2024-02-01'),
      leaseEndDate: new Date('2025-01-31'),
      monthlyRent: 800000,
      securityDeposit: 800000,
      rentDueDay: 1,
      status: 'active',
      moveInDate: new Date('2024-02-01'),
      isPrimaryTenant: true,
    },
  })

  const tenant3 = await prisma.tenant.create({
    data: {
      companyId: company1.id,
      unitId: units[2].id,
      firstName: 'Grace',
      lastName: 'Nakato',
      email: 'grace.nakato@email.com',
      phone: '+256703456789',
      passwordHash: hashedPassword,
      nationalId: 'CF345678901CDE',
      emergencyContactName: 'Peter Nakato',
      emergencyContactPhone: '+256704567890',
      leaseStartDate: new Date('2024-03-01'),
      leaseEndDate: new Date('2026-02-28'),
      monthlyRent: 1200000,
      securityDeposit: 1200000,
      rentDueDay: 1,
      status: 'active',
      moveInDate: new Date('2024-03-01'),
      isPrimaryTenant: true,
    },
  })

  const tenant4 = await prisma.tenant.create({
    data: {
      companyId: company1.id,
      unitId: units[3].id,
      firstName: 'David',
      lastName: 'Kato',
      email: 'david.kato@email.com',
      phone: '+256704567890',
      passwordHash: hashedPassword,
      nationalId: 'CM456789012DEF',
      emergencyContactName: 'Sarah Kato',
      emergencyContactPhone: '+256705678901',
      leaseStartDate: new Date('2024-04-01'),
      leaseEndDate: new Date('2025-03-31'),
      monthlyRent: 1200000,
      securityDeposit: 1200000,
      rentDueDay: 1,
      status: 'active',
      moveInDate: new Date('2024-04-01'),
      isPrimaryTenant: true,
    },
  })

  const tenant5 = await prisma.tenant.create({
    data: {
      companyId: company1.id,
      unitId: units[4].id,
      firstName: 'Ann',
      lastName: 'Mugisha',
      email: 'ann.mugisha@email.com',
      phone: '+256705678901',
      passwordHash: hashedPassword,
      nationalId: 'CF567890123EFG',
      emergencyContactName: 'John Mugisha',
      emergencyContactPhone: '+256706789012',
      leaseStartDate: new Date('2024-05-01'),
      leaseEndDate: new Date('2026-04-30'),
      monthlyRent: 1200000,
      securityDeposit: 1200000,
      rentDueDay: 1,
      status: 'active',
      moveInDate: new Date('2024-05-01'),
      isPrimaryTenant: true,
    },
  })

  // Create tenant-user relationships
  await prisma.tenantUser.create({
    data: {
      userId: admin1.id,
      tenantId: tenant1.id,
      canMakePayments: true,
      canRequestMaintenance: true,
      canViewDocuments: true,
    },
  })

  // Create technicians
  console.log('🔧 Creating technicians...')
  const technician1 = await prisma.technician.create({
    data: {
      companyId: company1.id,
      firstName: 'James',
      lastName: 'Oduya',
      email: 'james.oduya@propmaster.io',
      phone: '+256706789012',
      passwordHash: hashedPassword,
      address: 'Plot 789, Makerere Road, Kampala',
      specialization: 'plumbing',
      experienceYears: 5,
      certifications: JSON.stringify(['Licensed Plumber', 'Safety Training']),
      completedRequests: 45,
      averageRating: 4.8,
      totalEarnings: 15000000, // 15M UGX
      status: 'active',
      hireDate: new Date('2023-01-15'),
      emergencyContactName: 'Mary Oduya',
      emergencyContactPhone: '+256707890123',
    },
  })

  const technician2 = await prisma.technician.create({
    data: {
      companyId: company1.id,
      firstName: 'Peter',
      lastName: 'Ssali',
      email: 'peter.ssali@propmaster.io',
      phone: '+256707890123',
      passwordHash: hashedPassword,
      address: 'Plot 890, Entebbe Road, Kampala',
      specialization: 'electrical',
      experienceYears: 7,
      certifications: JSON.stringify(['Licensed Electrician', 'Advanced Electrical Safety']),
      completedRequests: 62,
      averageRating: 4.9,
      totalEarnings: 22000000, // 22M UGX
      status: 'active',
      hireDate: new Date('2022-08-01'),
      emergencyContactName: 'Grace Ssali',
      emergencyContactPhone: '+256708901234',
    },
  })

  const technician3 = await prisma.technician.create({
    data: {
      companyId: company1.id,
      firstName: 'Sarah',
      lastName: 'Nakato',
      email: 'sarah.nakato@propmaster.io',
      phone: '+256708901234',
      passwordHash: hashedPassword,
      address: 'Plot 901, Masaka Road, Kampala',
      specialization: 'general',
      experienceYears: 3,
      certifications: JSON.stringify(['General Maintenance', 'Customer Service']),
      completedRequests: 28,
      averageRating: 4.6,
      totalEarnings: 8500000, // 8.5M UGX
      status: 'active',
      hireDate: new Date('2023-06-01'),
      emergencyContactName: 'David Nakato',
      emergencyContactPhone: '+256709012345',
    },
  })

  // Create wallets for users, tenants, and technicians
  console.log('💰 Creating wallets...')
  const adminWallet = await prisma.wallet.create({
    data: {
      userType: 'user',
      userId: admin1.id,
      companyId: company1.id,
      currencyId: ugxCurrency.id,
      balance: 5000000, // 5M UGX
      status: 'active',
    },
  })

  const tenant1Wallet = await prisma.wallet.create({
    data: {
      userType: 'tenant',
      tenantId: tenant1.id,
      companyId: company1.id,
      currencyId: ugxCurrency.id,
      balance: 2000000, // 2M UGX
      status: 'active',
    },
  })

  const technician1Wallet = await prisma.wallet.create({
    data: {
      userType: 'technician',
      technicianId: technician1.id,
      companyId: company1.id,
      currencyId: ugxCurrency.id,
      balance: 1500000, // 1.5M UGX
      status: 'active',
    },
  })

  const technician2Wallet = await prisma.wallet.create({
    data: {
      userType: 'technician',
      technicianId: technician2.id,
      companyId: company1.id,
      currencyId: ugxCurrency.id,
      balance: 2200000, // 2.2M UGX
      status: 'active',
    },
  })

  // Create wallet transactions
  console.log('💸 Creating wallet transactions...')
  await prisma.walletTransaction.create({
    data: {
      walletId: adminWallet.id,
      companyId: company1.id,
      transactionType: 'top_up',
      amount: 5000000,
      currency: 'UGX',
      description: 'Initial wallet funding',
      paymentMethod: 'cash',
      status: 'completed',
    },
  })

  await prisma.walletTransaction.create({
    data: {
      walletId: tenant1Wallet.id,
      companyId: company1.id,
      transactionType: 'top_up',
      amount: 2000000,
      currency: 'UGX',
      description: 'Security deposit refund',
      paymentMethod: 'bank_transfer',
      status: 'completed',
    },
  })

  await prisma.walletTransaction.create({
    data: {
      walletId: technician1Wallet.id,
      companyId: company1.id,
      transactionType: 'top_up',
      amount: 1500000,
      currency: 'UGX',
      description: 'Monthly earnings',
      paymentMethod: 'cash',
      status: 'completed',
    },
  })

  await prisma.walletTransaction.create({
    data: {
      walletId: technician2Wallet.id,
      companyId: company1.id,
      transactionType: 'top_up',
      amount: 2200000,
      currency: 'UGX',
      description: 'Monthly earnings',
      paymentMethod: 'cash',
      status: 'completed',
    },
  })

  // Create maintenance requests
  console.log('🔧 Creating maintenance requests...')
  await prisma.maintenanceRequest.create({
    data: {
      propertyId: property1.id,
      tenantId: tenant1.id,
      companyId: company1.id,
      assignedToId: technician1.id,
      title: 'Leaking faucet in kitchen',
      description: 'The kitchen faucet has been leaking for 3 days. Water pressure is also low.',
      category: 'plumbing',
      priority: 'medium',
      status: 'completed',
      requestedDate: new Date('2024-10-01'),
      scheduledDate: new Date('2024-10-02'),
      completedDate: new Date('2024-10-02'),
      estimatedCost: 50000,
      actualCost: 45000,
      tenantNotes: 'Please fix as soon as possible, affecting daily use.',
      internalNotes: 'Replaced washer and cleaned aerator. Working perfectly now.',
    },
  })

  await prisma.maintenanceRequest.create({
    data: {
      propertyId: property1.id,
      tenantId: tenant2.id,
      companyId: company1.id,
      assignedToId: technician2.id,
      title: 'Power outage in bedroom',
      description: 'Light bulb socket not working, no power to bedroom lights.',
      category: 'electrical',
      priority: 'high',
      status: 'in_progress',
      requestedDate: new Date('2024-10-10'),
      scheduledDate: new Date('2024-10-11'),
      estimatedCost: 30000,
      tenantNotes: 'Very urgent, can\'t use bedroom at night.',
      internalNotes: 'Need to check wiring and replace socket.',
    },
  })

  await prisma.maintenanceRequest.create({
    data: {
      propertyId: property2.id,
      tenantId: tenant3.id,
      companyId: company1.id,
      assignedToId: technician3.id,
      title: 'Broken window lock',
      description: 'Window lock in living room is broken, cannot secure the window.',
      category: 'security',
      priority: 'medium',
      status: 'open',
      requestedDate: new Date('2024-10-12'),
      estimatedCost: 25000,
      tenantNotes: 'Security concern, please prioritize.',
    },
  })

  // Create payments
  console.log('💳 Creating payments...')
  await prisma.payment.create({
    data: {
      tenantId: tenant1.id,
      unitId: units[0].id,
      companyId: company1.id,
      amount: 800000,
      paymentType: 'rent',
      description: 'October 2024 Rent Payment',
      dueDate: new Date('2024-10-01'),
      paidDate: new Date('2024-10-01'),
      status: 'paid',
      paymentMethod: 'bank_transfer',
      bankTransferReference: 'REF001234',
    },
  })

  await prisma.payment.create({
    data: {
      tenantId: tenant2.id,
      unitId: units[1].id,
      companyId: company1.id,
      amount: 800000,
      paymentType: 'rent',
      description: 'October 2024 Rent Payment',
      dueDate: new Date('2024-10-01'),
      paidDate: new Date('2024-09-28'),
      status: 'paid',
      paymentMethod: 'mobile_money',
      mobileMoneyProvider: 'MTN',
      mobileMoneyReference: 'MM234567',
      mobileMoneyPhone: '+256702345678',
    },
  })

  await prisma.payment.create({
    data: {
      tenantId: tenant3.id,
      unitId: units[2].id,
      companyId: company1.id,
      amount: 1200000,
      paymentType: 'rent',
      description: 'October 2024 Rent Payment',
      dueDate: new Date('2024-10-01'),
      paidDate: new Date('2024-10-05'),
      status: 'paid',
      paymentMethod: 'cash',
    },
  })

  // Create expenses
  console.log('💸 Creating expenses...')
  await prisma.expense.create({
    data: {
      companyId: company1.id,
      propertyId: property1.id,
      title: 'Plumbing supplies for maintenance',
      description: 'Purchased pipes, fittings, and tools for plumbing repairs',
      category: 'maintenance',
      amount: 500000,
      expenseDate: new Date('2024-10-01'),
      status: 'paid',
      paymentMethod: 'cash',
      requestedBy: admin1.id,
      approvedBy: admin1.id,
      approvedAt: new Date('2024-10-01'),
      vendor: 'Kampala Hardware Store',
    },
  })

  await prisma.expense.create({
    data: {
      companyId: company1.id,
      title: 'Office supplies',
      description: 'Stationery, printer ink, and cleaning supplies',
      category: 'office_supplies',
      amount: 200000,
      expenseDate: new Date('2024-10-05'),
      status: 'paid',
      paymentMethod: 'bank_transfer',
      requestedBy: admin1.id,
      approvedBy: admin1.id,
      approvedAt: new Date('2024-10-05'),
      vendor: 'Office Depot Uganda',
    },
  })

  console.log('✅ Database seeding completed successfully!')
  console.log('📊 Summary:')
  console.log(`   - ${2} Companies created`)
  console.log(`   - ${4} Users created`)
  console.log(`   - ${2} Estates created`)
  console.log(`   - ${3} Properties created`)
  console.log(`   - ${10} Units created`)
  console.log(`   - ${5} Tenants created`)
  console.log(`   - ${3} Technicians created`)
  console.log(`   - ${5} Wallets created`)
  console.log(`   - ${4} Wallet transactions created`)
  console.log(`   - ${3} Maintenance requests created`)
  console.log(`   - ${3} Payments created`)
  console.log(`   - ${2} Expenses created`)
  console.log('')
  console.log('🔐 Default login credentials:')
  console.log('   Admin: admin@propmaster.io / password123')
  console.log('   Tenant: richardmiyingo@gmail.com / password123')
  console.log('   Technician: james.oduya@propmaster.io / password123')
}

main()
  .catch((e) => {
    console.error('❌ Error seeding database:', e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })