// prisma/seed.ts
import { PrismaClient } from '@prisma/client'
import bcrypt from 'bcryptjs'
import seedData from '../lib/dbSeed.ts'

const prisma = new PrismaClient()

async function main() {
  console.log('🌱 Seeding Uwezo Fund HRMS Database...')
  console.log('='.repeat(50))

  // Clear existing data
  console.log('Clearing existing data...')
  await prisma.leaveRequest.deleteMany({})
  await prisma.leaveBalance.deleteMany({})
  await prisma.session.deleteMany({})
  await prisma.user.deleteMany({})
  await prisma.employee.deleteMany({})
  await prisma.leavePolicy.deleteMany({})
  await prisma.department.deleteMany({})
  await prisma.holiday.deleteMany({})
  await prisma.companyGoal.deleteMany({})
  await prisma.hODAccount.deleteMany({})  // Note: hODAccount (capital H, capital O, capital D)
  await prisma.trainingProgram.deleteMany({})
  await prisma.disciplinaryCase.deleteMany({})
  await prisma.payrollRecord.deleteMany({})

  // 1. Create Departments
  console.log('Creating departments...')
  for (const dept of seedData.SEED_DEPARTMENTS) {
    await prisma.department.create({
      data: {
        name: dept.name,
        code: dept.code,
        description: dept.description,
        isActive: true,
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_DEPARTMENTS.length} departments`)

  // 2. Create Leave Policies
  console.log('Creating leave policies...')
  for (const policy of seedData.SEED_LEAVE_POLICIES) {
    await prisma.leavePolicy.create({
      data: {
        type: policy.type,
        label: policy.label,
        entitlement: policy.entitlement,
        internEntitlement: policy.intern_entitlement,
        accrualRate: policy.accrual_rate,
        maxCarryover: policy.max_carryover,
        requiresDocument: policy.requires_document,
        unpaidAllowed: policy.unpaid_allowed || false,
        color: policy.color,
        icon: policy.icon,
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_LEAVE_POLICIES.length} leave policies`)

  // 3. Create Employees
  console.log('Creating employees...')
  const employees = []
  for (const emp of seedData.SEED_EMPLOYEES) {
    const employee = await prisma.employee.create({
      data: {
        employeeNumber: emp.employee_number,
        firstName: emp.first_name,
        lastName: emp.last_name,
        fullName: emp.full_name,
        email: emp.email,
        phone: emp.phone,
        gender: emp.gender,
        employmentType: emp.employment_type,
        dept: emp.dept,
        position: emp.position,
        joinDate: new Date(emp.join_date),
        salary: emp.salary,
        isIntern: emp.is_intern,
        isActive: true,
      },
    })
    employees.push(employee)
  }
  console.log(`✓ Created ${employees.length} employees`)

  // 4. Create Users
  console.log('Creating users...')
  for (const user of seedData.SEED_USERS) {
    const hashedPassword = await bcrypt.hash(`${user.username}@2026`, 10)
    const linkEmployee = employees.find(emp => emp.email === user.email)
    await prisma.user.create({
      data: {
        username: user.username,
        passwordHash: hashedPassword,
        email: user.email,
        name: user.name,
        role: user.role,
        dept: user.dept,
        position: user.position,
        employeeId: linkEmployee ? linkEmployee.employeeNumber : undefined,
        isFirstLogin: true,
        isActive: true,
        isIntern: user.is_intern,
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_USERS.length} users`)

  // 5. Create HOD Accounts
  console.log('Creating HOD accounts...')
  const dbUsers = await prisma.user.findMany()
  for (const hod of seedData.SEED_HOD_ACCOUNTS) {
    const user = dbUsers.find((u: { username: string }) => u.username === hod.username)
    if (user) {
      await prisma.hODAccount.create({  // Note: hODAccount
        data: {
          userId: user.id,
          username: hod.username,
          dept: hod.dept,
          mustChangePassword: hod.must_change_password,
          isActive: true,
        },
      })
    }
  }
  console.log(`✓ Created ${seedData.SEED_HOD_ACCOUNTS.length} HOD accounts`)

  // 6. Create Public Holidays
  console.log('Creating public holidays...')
  for (const holiday of seedData.SEED_PUBLIC_HOLIDAYS) {
    await prisma.holiday.create({
      data: {
        date: new Date(holiday.date),
        name: holiday.name,
        isRecurring: false,
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_PUBLIC_HOLIDAYS.length} public holidays`)

  // 7. Create Company Goals
  console.log('Creating company goals...')
  for (const goal of seedData.SEED_COMPANY_GOALS) {
    await prisma.companyGoal.create({
      data: {
        kra: goal.kra,
        title: goal.title,
        description: goal.description,
        target: goal.target,
        fiscalYear: goal.fiscal_year,
        progress: goal.progress,
        createdBy: 'admin',
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_COMPANY_GOALS.length} company goals`)

  // 8. Create Training Programs
  console.log('Creating training programs...')
  for (const program of seedData.SEED_TRAINING_PROGRAMS) {
    await prisma.trainingProgram.create({
      data: {
        title: program.title,
        dept: program.dept,
        trainer: program.trainer,
        mode: program.mode,
        cost: program.cost,
        capacity: program.capacity,
        enrolled: program.enrolled,
        status: program.status,
        venue: program.venue || null,
        startDate: new Date(program.start_date),
        endDate: new Date(program.end_date),
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_TRAINING_PROGRAMS.length} training programs`)

  // 9. Create Disciplinary Cases
  console.log('Creating disciplinary cases...')
  for (const disciplinary of seedData.SEED_DISCIPLINARY_CASES) {
    await prisma.disciplinaryCase.create({
      data: {
        caseNumber: disciplinary.case_number,
        employeeName: disciplinary.employee_name,
        dept: disciplinary.dept,
        offenceType: disciplinary.offence_type,
        offenceDate: new Date(),
        description: disciplinary.description,
        status: disciplinary.status,
        severity: disciplinary.severity,
        createdBy: disciplinary.created_by,
      },
    })
  }
  console.log(`✓ Created ${seedData.SEED_DISCIPLINARY_CASES.length} disciplinary cases`)

  // 10. Create Payroll Records
  console.log('Creating payroll records...')
  for (const payroll of seedData.SEED_PAYROLL_EMPLOYEES) {
    const employee = employees.find((e: { employeeNumber: string }) => e.employeeNumber === payroll.employee_number)
    if (employee) {
      const grossPay = payroll.basic_salary + payroll.house_allowance + payroll.transport_allowance
      const netPay = grossPay - payroll.paye - payroll.nhif - payroll.nssf
      await prisma.payrollRecord.create({
        data: {
          employeeId: employee.id,
          month: 5,
          year: 2026,
          basicSalary: payroll.basic_salary,
          houseAllowance: payroll.house_allowance,
          transportAllowance: payroll.transport_allowance,
          otherAllowances: 0,
          grossPay: grossPay,
          paye: payroll.paye,
          nhif: payroll.nhif,
          nssf: payroll.nssf,
          otherDeductions: 0,
          netPay: netPay,
          status: 'Draft',
        },
      })
    }
  }
  console.log(`✓ Created ${seedData.SEED_PAYROLL_EMPLOYEES.length} payroll records`)

  // 11. Create Leave Balances
  console.log('Creating leave balances...')
  const policies = await prisma.leavePolicy.findMany()
  const fiscalYear = '2025/2026'
  let balanceCount = 0
  for (const employee of employees) {
    for (const policy of policies) {
      const entitlement = employee.isIntern ? policy.internEntitlement : policy.entitlement
      await prisma.leaveBalance.create({
        data: {
          employeeId: employee.id,
          policyId: policy.id,
          fiscalYear,
          entitlement,
          remaining: entitlement,
          taken: 0,
          carryover: 0,
        },
      })
      balanceCount++
    }
  }
  console.log(`✓ Created ${balanceCount} leave balances for ${employees.length} employees`)

  console.log('='.repeat(50))
  console.log('✅ SEEDING COMPLETED SUCCESSFULLY!')
  console.log('='.repeat(50))
  console.log('\n🔐 LOGIN CREDENTIALS:')
  console.log('   📧 Admin: admin@uwezo.go.ke / admin@2026')
  console.log('   📧 HR Manager: grace.njoroge@uwezo.go.ke / hr.manager@2026')
  console.log('   📧 HOD ICT: gedion.njoroge@uwezo.go.ke / hod.ict@2026')
  console.log('   📧 HOD M&E: evans.oyaro@uwezo.go.ke / hod.me@2026')
  console.log('   📧 HOD Transport: margaret.murithi@uwezo.go.ke / hod.transport@2026')
  console.log('   📧 HOD Procurement: laban.mwangi@uwezo.go.ke / hod.procurement@2026')
  console.log('   📧 HOD Comms: benadette.owade@uwezo.go.ke / hod.comms@2026')
  console.log('   📧 HOS: peter.lengapiani@uwezo.go.ke / hos@2026')
  console.log('   📧 Finance: patrick.odhiambo@uwezo.go.ke / finance.officer@2026')
  console.log('   📧 Employee (Jane): jane.mwangi@uwezo.go.ke / uf001@2026')
  console.log('   📧 Employee (Peter): peter.otieno@uwezo.go.ke / uf002@2026')
  console.log('   📧 IT Intern: kevin.ochieng@uwezo.go.ke / int001@2026')
  console.log('   📧 M&E Intern: faith.achieng@uwezo.go.ke / int002@2026')
  console.log('\n⚠️  All users must change password on first login!')
  console.log('📁 Database file: dev.db')
}

main()
  .catch((e) => {
    console.error('❌ Seeding failed:', e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })