<?php

namespace Database\Seeders;

use App\Models\AttendanceRecord;
use App\Models\Department;
use App\Models\DutyRoster;
use App\Models\DutyShift;
use App\Models\Employee;
use App\Models\EmployeeLoan;
use App\Models\Hotel;
use App\Models\LeaveRequest;
use App\Models\Payslip;
use App\Support\Tenancy;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;

class HrSeeder extends Seeder
{
    public function run(): void
    {
        Tenancy::set(Hotel::first());

        $departments = collect(['Front Office', 'Kitchen', 'Housekeeping', 'Finance'])
            ->mapWithKeys(fn ($name) => [$name => Department::create(['name' => $name])]);

        $shifts = [
            'Morning' => DutyShift::create(['name' => 'Morning', 'starts_at' => '06:00:00', 'ends_at' => '14:00:00']),
            'Afternoon' => DutyShift::create(['name' => 'Afternoon', 'starts_at' => '14:00:00', 'ends_at' => '22:00:00']),
            'Night' => DutyShift::create(['name' => 'Night', 'starts_at' => '22:00:00', 'ends_at' => '06:00:00']),
        ];

        $employees = collect([
            ['Blessing Adeyemi', 'Front Office', 'Front Desk Officer', 180000],
            ['Chinedu Okafor', 'Front Office', 'Reservations Agent', 150000],
            ['Chef Emeka Obi', 'Kitchen', 'Executive Chef', 450000],
            ['Kunle Ajayi', 'Kitchen', 'Line Cook', 130000],
            ['Sandra George', 'Kitchen', 'Pastry Chef', 200000],
            ['Mary Danladi', 'Housekeeping', 'Head Housekeeper', 160000],
            ['Peter Eze', 'Housekeeping', 'Room Attendant', 95000],
            ['Ibrahim Musa', 'Finance', 'Senior Accountant', 350000],
        ])->map(fn ($e) => Employee::create([
            'employee_no' => 'EMP-' . strtoupper(Str::random(6)),
            'name' => $e[0],
            'email' => Str::slug($e[0]) . '@epelcon.com',
            'phone' => '+234 80' . rand(10000000, 99999999),
            'department_id' => $departments[$e[1]]->id,
            'designation' => $e[2],
            'employment_type' => 'full_time',
            'date_joined' => now()->subMonths(rand(3, 36)),
            'salary' => $e[3],
            'bank_name' => collect(['GTBank', 'Access', 'Zenith', 'UBA'])->random(),
            'account_number' => '0' . rand(100000000, 999999999),
        ]));

        // 5 working days of attendance
        foreach ($employees as $employee) {
            for ($i = 5; $i >= 1; $i--) {
                $date = now()->subDays($i);

                if ($date->isWeekend()) {
                    continue;
                }

                $roll = rand(1, 100);
                $status = $roll <= 85 ? 'present' : ($roll <= 92 ? 'late' : ($roll <= 96 ? 'half_day' : 'absent'));

                AttendanceRecord::create([
                    'employee_id' => $employee->id,
                    'date' => $date->toDateString(),
                    'clock_in' => $status !== 'absent' ? ($status === 'late' ? '08:45:00' : '07:55:00') : null,
                    'clock_out' => $status !== 'absent' ? ($status === 'half_day' ? '12:30:00' : '17:05:00') : null,
                    'status' => $status,
                ]);
            }
        }

        // Leave requests
        LeaveRequest::create([
            'employee_id' => $employees[3]->id,
            'type' => 'annual',
            'start_date' => now()->addDays(7)->toDateString(),
            'end_date' => now()->addDays(11)->toDateString(),
            'days' => 5,
            'reason' => 'Family wedding',
            'status' => 'pending',
        ]);

        LeaveRequest::create([
            'employee_id' => $employees[6]->id,
            'type' => 'sick',
            'start_date' => now()->subDays(2)->toDateString(),
            'end_date' => now()->addDay()->toDateString(),
            'days' => 4,
            'reason' => 'Malaria treatment',
            'status' => 'approved',
        ]);

        // This week's roster: assign each employee a morning or afternoon shift on 3 days
        $startOfWeek = now()->startOfWeek();

        foreach ($employees as $idx => $employee) {
            $shift = $idx % 2 === 0 ? $shifts['Morning'] : $shifts['Afternoon'];

            foreach ([0, 2, 4] as $offset) {
                DutyRoster::create([
                    'employee_id' => $employee->id,
                    'duty_shift_id' => $shift->id,
                    'date' => $startOfWeek->copy()->addDays($offset)->toDateString(),
                ]);
            }
        }

        // Active loan
        EmployeeLoan::create([
            'employee_id' => $employees[4]->id,
            'amount' => 300000,
            'monthly_deduction' => 30000,
            'balance' => 210000,
            'reason' => 'Emergency medical bill',
            'status' => 'active',
            'issued_on' => now()->subMonths(3)->toDateString(),
        ]);

        // Last month's payslips (all paid)
        $lastMonth = now()->subMonth()->format('Y-m');

        foreach ($employees as $employee) {
            Payslip::create([
                'employee_id' => $employee->id,
                'month' => $lastMonth,
                'gross' => $employee->salary,
                'allowances' => 0,
                'deductions' => 0,
                'loan_deduction' => 0,
                'net' => $employee->salary,
                'status' => 'paid',
                'paid_at' => now()->subMonth()->endOfMonth(),
            ]);
        }
    }
}
