<?php

namespace Database\Seeders\Dummy;

use App\Models\Tenants\Leave;
use Database\Seeders\DummyDataSeeder;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class DummyLeaveSeeder extends Seeder
{
    public function run(): void
    {
        $tenantId = DummyDataSeeder::TENANT_ID;
        $userId = DummyDataSeeder::USER_ID;

        // 테넌트 소속 사용자 조회
        $userIds = DB::table('user_tenants')
            ->where('tenant_id', $tenantId)
            ->pluck('user_id')
            ->toArray();

        if (empty($userIds)) {
            $this->command->warn('   ⚠ leaves: 사용자가 없습니다');

            return;
        }

        // 휴가 유형 (가중치)
        $leaveTypes = [
            'annual' => 50,       // 연차 50%
            'half_am' => 15,      // 오전 반차 15%
            'half_pm' => 15,      // 오후 반차 15%
            'sick' => 10,         // 병가 10%
            'family' => 5,        // 경조사 5%
            'other' => 5,         // 기타 5%
        ];

        // 상태 (가중치)
        $statuses = [
            'approved' => 60,     // 승인 60%
            'pending' => 25,      // 대기 25%
            'rejected' => 10,     // 반려 10%
            'cancelled' => 5,     // 취소 5%
        ];

        $count = 0;
        $year = 2025;

        // 사용자별로 1~4건의 휴가 생성
        foreach ($userIds as $uId) {
            $leaveCount = rand(1, 4);

            for ($i = 0; $i < $leaveCount; $i++) {
                $month = rand(1, 12);
                $day = rand(1, 28);
                $startDate = sprintf('%04d-%02d-%02d', $year, $month, $day);

                $leaveType = $this->getRandomWeighted($leaveTypes);
                $status = $this->getRandomWeighted($statuses);

                // 휴가 일수 결정
                if (in_array($leaveType, ['half_am', 'half_pm'])) {
                    $days = 0.5;
                    $endDate = $startDate;
                } else {
                    $days = rand(1, 3);
                    $endDate = date('Y-m-d', strtotime($startDate.' + '.($days - 1).' days'));
                }

                // 승인자 정보
                $approvedBy = null;
                $approvedAt = null;
                $rejectReason = null;

                if ($status === 'approved') {
                    $approvedBy = $userId;
                    $approvedAt = date('Y-m-d H:i:s', strtotime($startDate.' - 2 days'));
                } elseif ($status === 'rejected') {
                    $approvedBy = $userId;
                    $approvedAt = date('Y-m-d H:i:s', strtotime($startDate.' - 2 days'));
                    $rejectReason = '업무 일정 상 불가';
                }

                Leave::create([
                    'tenant_id' => $tenantId,
                    'user_id' => $uId,
                    'leave_type' => $leaveType,
                    'start_date' => $startDate,
                    'end_date' => $endDate,
                    'days' => $days,
                    'reason' => $this->getLeaveReason($leaveType),
                    'status' => $status,
                    'approved_by' => $approvedBy,
                    'approved_at' => $approvedAt,
                    'reject_reason' => $rejectReason,
                    'created_by' => $uId,
                ]);

                $count++;
            }
        }

        $this->command->info('   ✓ leaves: '.$count.'건 생성');
    }

    private function getRandomWeighted(array $weights): string
    {
        $total = array_sum($weights);
        $rand = rand(1, $total);
        $cumulative = 0;

        foreach ($weights as $key => $weight) {
            $cumulative += $weight;
            if ($rand <= $cumulative) {
                return $key;
            }
        }

        return array_key_first($weights);
    }

    private function getLeaveReason(string $type): string
    {
        return match ($type) {
            'annual' => '개인 휴가',
            'half_am' => '오전 병원 방문',
            'half_pm' => '오후 개인 일정',
            'sick' => '건강 사유',
            'family' => '가족 행사',
            'maternity' => '출산 휴가',
            'parental' => '육아 휴직',
            default => '개인 사유',
        };
    }
}
