<?php

namespace App\Modules\HR\Core\Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Faker\Factory as Faker;
use App\Modules\PLATFORM\Settings\Models\Branch;
use App\Modules\PLATFORM\Settings\Models\Country;
use App\Modules\PLATFORM\Settings\Models\City;
use App\Modules\HR\Core\Models\Gender;
use App\Modules\HR\Core\Models\MaritalStatus;
use App\Modules\HR\Core\Models\BloodGroup;
use App\Modules\HR\Core\Models\RelationshipType;
use App\Modules\HR\Core\Models\IdentificationType;
use App\Modules\HR\Core\Models\DocumentType;
use App\Modules\HR\Core\Models\EmploymentType;
use App\Modules\HR\Core\Models\Department;
use App\Modules\HR\Core\Models\Designation;
use App\Modules\HR\Core\Models\Grade;
use App\Modules\HR\Core\Models\Shift;
use App\Modules\HR\Core\Models\ShiftSegment;
use App\Modules\HR\Payroll\Models\PayrollGroup;
use App\Modules\HR\Core\Models\Employee;

class HREmployeeSeeder extends Seeder
{
    public function run()
    {
        $faker = Faker::create();

        // 1. Ensure Branch
        $branch = Branch::first();
        if (!$branch) {
            $branch = Branch::create([
                'branch_code' => 'BR-001',
                'name' => 'Main Branch',
                'status' => true,
            ]);
        }

        // 2. Ensure Country & City
        $country = Country::first();
        if (!$country) {
            $country = Country::create([
                'name' => 'Sri Lanka',
                'code' => 'LK',
                'status' => true,
            ]);
        }
        $city = City::first();
        if (!$city) {
            $city = City::create([
                'country_id' => $country->id,
                'name' => 'Colombo',
                'status' => true,
            ]);
        }

        // 3. Seed Dictionaries
        $genders = ['Male', 'Female'];
        foreach ($genders as $name) {
            Gender::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        $maritalStatuses = ['Single', 'Married', 'Divorced'];
        foreach ($maritalStatuses as $name) {
            MaritalStatus::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        $bloodGroups = ['A+', 'A-', 'B+', 'B-', 'O+', 'O-', 'AB+', 'AB-'];
        foreach ($bloodGroups as $name) {
            BloodGroup::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        $idTypes = ['NIC', 'Passport', 'Driving License'];
        foreach ($idTypes as $name) {
            IdentificationType::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'country_id' => $country->id, 'status' => true]
            );
        }

        $docTypes = ['CV', 'Offer Letter', 'Contract'];
        foreach ($docTypes as $name) {
            DocumentType::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        // 4. Seed Organizational Structure
        $empTypes = ['Permanent', 'Probation', 'Contract', 'Intern'];
        foreach ($empTypes as $name) {
            EmploymentType::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        $departments = ['Human Resources', 'Finance', 'IT', 'Operations', 'Sales'];
        foreach ($departments as $name) {
            Department::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'code' => strtoupper(substr($name, 0, 3)), 'status' => true]
            );
        }

        $designations = ['Manager', 'Assistant Manager', 'Executive', 'Associate', 'Intern'];
        foreach ($designations as $name) {
            Designation::firstOrCreate(
                ['title' => $name],
                ['branch_id' => $branch->id, 'code' => strtoupper(substr($name, 0, 3)), 'level' => 1, 'status' => true]
            );
        }

        $grades = ['G-1', 'G-2', 'G-3', 'G-4'];
        foreach ($grades as $name) {
            Grade::firstOrCreate(
                ['code' => $name],
                ['branch_id' => $branch->id, 'status' => true]
            );
        }

        // 5. Seed Payroll Groups
        $payrollGroups = ['Monthly Executive', 'Monthly Staff'];
        foreach ($payrollGroups as $name) {
            PayrollGroup::firstOrCreate(
                ['name' => $name],
                ['branch_id' => $branch->id, 'code' => strtoupper(str_replace(' ', '', $name)), 'status' => true]
            );
        }

        // 6. Seed Shift
        $shift = Shift::firstOrCreate(
            ['name' => 'General Shift'],
            [
                'branch_id' => $branch->id,
                'code' => 'GEN',
                'work_start_time' => '09:00:00',
                'work_end_time' => '17:00:00',
                'status' => true
            ]
        );
        
        $segment = ShiftSegment::firstOrCreate(
            ['name' => 'General Roster'],
            [
                'branch_id' => $branch->id,
                'effective_from' => now()->startOfYear(),
                'status' => true
            ]
        );

        // 7. Seed Teams
        $teams = ['Development Team', 'Sales Team', 'Admin Team'];
        foreach ($teams as $name) {
            // Check if Team model uses BranchScoped or has branch_id
            // Assuming it does based on pattern, but if migration didn't enforce it, we'll check.
            // For safety, providing branch_id if fillable.
            try {
                \App\Modules\HR\Core\Models\Team::firstOrCreate(
                    ['name' => $name],
                    ['branch_id' => $branch->id, 'status' => true]
                );
            } catch (\Exception $e) {
                // Determine if code is required or name unique
            }
        }

        // Get Collections for Random Assignment
        $genderIds = Gender::pluck('id')->toArray();
        $msIds = MaritalStatus::pluck('id')->toArray();
        $bgIds = BloodGroup::pluck('id')->toArray();
        $deptIds = Department::pluck('id')->toArray();
        $desigIds = Designation::pluck('id')->toArray();
        $gradeIds = Grade::pluck('id')->toArray();
        $pgIds = PayrollGroup::pluck('id')->toArray();
        $etIds = EmploymentType::pluck('id')->toArray();
        $teamIds = \App\Modules\HR\Core\Models\Team::pluck('id')->toArray();
        $idTypeIds = IdentificationType::pluck('id')->toArray();
        $countryId = $country->id;
        $cityId = $city->id;
        $segId = $segment ? $segment->id : null;

        // 7. Seed 20 Employees
        for ($i = 0; $i < 20; $i++) {
            $firstName = $faker->firstName;
            $lastName = $faker->lastName;
            
            try {
                Employee::create([
                    'branch_id' => $branch->id,
                    'employee_code' => 'EMP-' . str_pad($i + 1, 4, '0', STR_PAD_LEFT),
                    'epf_no' => 'EPF-' . ($i + 1000),
                    'first_name' => $firstName,
                    'last_name' => $lastName,
                    'gender_id' => $faker->randomElement($genderIds),
                    'date_of_birth' => $faker->date('Y-m-d', '-20 years'),
                    'nationality_id' => $countryId,
                    'marital_status_id' => $faker->randomElement($msIds),
                    'blood_group_id' => $faker->randomElement($bgIds),
                    'status' => 'active',

                    // Employment
                    'department_id' => $faker->randomElement($deptIds),
                    'designation_id' => $faker->randomElement($desigIds),
                    'grade_id' => $faker->randomElement($gradeIds),
                    'team_id' => $faker->randomElement($teamIds),
                    'payroll_group_id' => $faker->randomElement($pgIds),
                    'employment_type_id' => $faker->randomElement($etIds),
                    'shift_segment_id' => $segId, // Can be null if segment creation failed
                    'date_of_joining' => $faker->date('Y-m-d', '-1 year'),
                    'employment_status' => 'active',

                    // Contact
                    'official_email' => strtolower($firstName . '.' . $lastName . $i . '@demo.com'),
                    'mobile_number' => $faker->phoneNumber,
                    
                    // Address
                    'current_city_id' => $cityId,
                    
                    // Statutory
                    'identification_type_id' => $faker->randomElement($idTypeIds),
                    'identification_number' => $faker->unique()->numerify('#########V'),
                ]);
            } catch (\Exception $e) {
                // Ignore specific errors (like unique constraint) and continue
                continue;
            }
        }
    }
}
