<?php

namespace Database\Seeders;

use App\Enums\DailyPatrolSummaryStatus;
use App\Enums\FlatStatus;
use App\Enums\Gender;
use App\Enums\PatrollingLocationType;
use App\Enums\PatrollingStatus;
use App\Enums\UserRole;
use App\Enums\VehicleType;
use App\Models\DailyPatrolSummary;
use App\Models\Flat;
use App\Models\Owner;
use App\Models\PatrollingLocation;
use App\Models\PatrollingLog;
use App\Models\PatrolRound;
use App\Models\User;
use App\Models\Vehicle;
use App\Models\Wing;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

class ComprehensiveDataSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $this->command->info('Starting comprehensive data seeding...');

        // Create Admin User
        $this->createAdminUser();

        // Create Wings, Flats, and Owners
        $this->createWingsFlatsAndOwners();

        // Create Vehicles for residents
        $this->createVehicles();

        // Create Patrolling Locations
        $this->createPatrollingLocations();

        // Create Patrol Rounds
        $this->createPatrolRounds();

        // Create Sample Patrol Logs and Summaries
        $this->createPatrolLogsAndSummaries();

        $this->command->info('Comprehensive data seeding completed successfully!');
    }

    private function createAdminUser(): void
    {
        $this->command->info('Creating admin user...');

        User::create([
            'name' => 'System Administrator',
            'email' => 'admin@residentialpatrol.com',
            'phone' => '9999999999',
            'password' => Hash::make('password'),
            'role' => UserRole::ADMIN,
            'gender' => Gender::MALE,
        ]);

        $this->command->info('Created admin user with email: admin@residentialpatrol.com');
    }

    private function createWingsFlatsAndOwners(): void
    {
        $this->command->info('Creating wings, flats, and owners...');

        $wingNames = ['A', 'B', 'C', 'D'];

        foreach ($wingNames as $wingName) {
            // Create Wing
            $wing = Wing::create([
                'name' => "Wing {$wingName}",
                'no_floors' => 2,
                'no_flats' => 8, // 2 floors × 4 flats per floor
                'no_lifts' => 1,
                'fire_extinguisher_date' => now()->addMonths(6)->format('Y-m-d'),
            ]);

            // Create Flats and Owners for each wing
            for ($floor = 1; $floor <= 2; $floor++) {
                for ($flatNum = 1; $flatNum <= 4; $flatNum++) {
                    $flatNumber = "{$wingName}{$floor}0{$flatNum}";

                    // Create Owner first
                    $owner = Owner::create([
                        'name' => "Resident {$flatNumber}",
                        'email' => "resident.{$flatNumber}@example.com",
                        'phone' => '9' . str_pad(rand(100000000, 999999999), 9, '0', STR_PAD_LEFT),
                        'aadhaar_no' => str_pad(rand(100000000000, 999999999999), 12, '0', STR_PAD_LEFT),
                        'pan_no' => 'PAN' . strtoupper(substr(md5($flatNumber), 0, 7)),
                    ]);

                    // Create Flat
                    $flat = Flat::create([
                        'flat_no' => $flatNumber,
                        'wing_id' => $wing->id,
                        'owner_id' => $owner->id,
                        'status' => collect([FlatStatus::ACTIVE, FlatStatus::ACTIVE, FlatStatus::ACTIVE, FlatStatus::IN_ACTIVE])->random(), // 75% active
                        'flat_sqrft' => rand(500, 1500),
                    ]);

                    // Create User for the Owner
                    User::create([
                        'owner_id' => $owner->id,
                        'flat_id' => $flat->id,
                        'name' => $owner->name,
                        'email' => $owner->email,
                        'phone' => $owner->phone,
                        'password' => Hash::make('password123'),
                        'role' => UserRole::OWNER,
                        'gender' => collect([Gender::MALE, Gender::FEMALE])->random(),
                        'relation' => 'self',
                    ]);
                }
            }
        }

        $this->command->info("Created 4 wings with 8 flats each (32 total flats and owners)");
    }

    private function createVehicles(): void
    {
        $this->command->info('Creating vehicles...');

        $owners = Owner::all();
        $flats = Flat::all();
        $vehicleCount = 0;

        foreach ($owners as $owner) {
            // Find the flat for this owner
            $flat = $flats->where('owner_id', $owner->id)->first();
            if (!$flat) continue;

            // 70% chance of having a vehicle, some owners might have 2 vehicles
            $hasVehicle = rand(1, 10) <= 7;
            $vehicleCountForOwner = $hasVehicle ? (rand(1, 10) <= 3 ? 2 : 1) : 0; // 30% chance of 2 vehicles if they have any

            for ($i = 0; $i < $vehicleCountForOwner; $i++) {
                $vehicleTypes = [VehicleType::TWO_WHEELER, VehicleType::FOUR_WHEELER];
                $vehicleType = collect($vehicleTypes)->random();

                $vehicleNumber = $this->generateVehicleNumber();
                $vehicleBrands = [
                    VehicleType::FOUR_WHEELER->value => ['Maruti', 'Hyundai', 'Tata', 'Honda', 'Toyota'],
                    VehicleType::TWO_WHEELER->value => ['Hero', 'Bajaj', 'TVS', 'Honda', 'Yamaha']
                ];

                Vehicle::create([
                    'owner_id' => $owner->id,
                    'flat_id' => $flat->id,
                    'vehicle_type' => $vehicleType,
                    'make' => collect($vehicleBrands[$vehicleType->value])->random(),
                    'model' => 'Model ' . rand(100, 999),
                    'color' => collect(['White', 'Black', 'Silver', 'Red', 'Blue', 'Grey'])->random(),
                    'registration_no' => $vehicleNumber,
                    'unique_code' => 'VEH' . str_pad($vehicleCount + 1, 6, '0', STR_PAD_LEFT),
                    'is_active' => rand(1, 10) <= 9, // 90% active
                ]);

                $vehicleCount++;
            }
        }

        $this->command->info("Created {$vehicleCount} vehicles for residents");
    }

    private function createPatrollingLocations(): void
    {
        $this->command->info('Creating patrolling locations...');

        $wings = Wing::all();

        $locations = [
            ['name' => 'Main Gate', 'type' => PatrollingLocationType::GATE, 'description' => 'Main entrance gate with security cabin'],
            ['name' => 'Exit Gate', 'type' => PatrollingLocationType::GATE, 'description' => 'Secondary exit gate'],
            ['name' => 'Central Garden', 'type' => PatrollingLocationType::GARDEN, 'description' => 'Central landscaped garden area'],
            ['name' => 'Visitor Parking', 'type' => PatrollingLocationType::PARKING, 'description' => 'Designated visitor parking area'],
            ['name' => 'Resident Parking', 'type' => PatrollingLocationType::PARKING, 'description' => 'Covered resident parking area'],
            ['name' => 'Children Playground', 'type' => PatrollingLocationType::PLAYGROUND, 'description' => 'Kids play area with equipment'],
            ['name' => 'Swimming Pool', 'type' => PatrollingLocationType::SWIMMING_POOL, 'description' => 'Community swimming pool area'],
            ['name' => 'Gymnasium', 'type' => PatrollingLocationType::GYM, 'description' => 'Community fitness center'],
            ['name' => 'Club House', 'type' => PatrollingLocationType::CLUB_HOUSE, 'description' => 'Community hall and meeting rooms'],
            ['name' => 'Maintenance Room', 'type' => PatrollingLocationType::OTHER, 'description' => 'Electrical and maintenance equipment room']
        ];

        foreach ($locations as $index => $locationData) {
            $wing = $wings->random(); // Randomly assign to a wing

            PatrollingLocation::create([
                'name' => $locationData['name'],
                'type' => $locationData['type'],
                'location_code' => 'LOC' . str_pad($index + 1, 3, '0', STR_PAD_LEFT),
                'description' => $locationData['description'],
                'wing_id' => $wing->id,
                'coordinates' => $this->generateCoordinates(),
                'is_active' => true,
            ]);
        }

        $this->command->info("Created 10 patrolling locations");
    }

    private function createPatrolRounds(): void
    {
        $this->command->info('Creating patrol rounds...');

        $rounds = [
            [
                'name' => 'Morning Security Round',
                'start_time' => '06:00',
                'end_time' => '10:00',
                'description' => 'Morning patrol covering all security checkpoints and common areas'
            ],
            [
                'name' => 'Evening Security Round',
                'start_time' => '18:00',
                'end_time' => '22:00',
                'description' => 'Evening patrol focusing on parking areas and perimeter security'
            ]
        ];

        foreach ($rounds as $roundData) {
            PatrolRound::create([
                'name' => $roundData['name'],
                'start_time' => $roundData['start_time'],
                'end_time' => $roundData['end_time'],
                'description' => $roundData['description'],
                'is_active' => true,
            ]);
        }

        $this->command->info("Created 2 patrol rounds");
    }

    private function createPatrolLogsAndSummaries(): void
    {
        $this->command->info('Creating sample patrol logs and summaries...');

        $guards = User::where('role', UserRole::GUARD->value)->get();
        $patrolRounds = PatrolRound::all();
        $locations = PatrollingLocation::all();

        $summaryCount = 0;
        $logCount = 0;

        // Create patrol data for the last 30 days
        for ($day = 30; $day >= 1; $day--) {
            $date = now()->subDays($day)->format('Y-m-d');

            foreach ($guards as $guard) {
                // 80% chance of patrol activity per day per guard
                if (rand(1, 10) <= 8) {
                    // Each guard might do 1-2 rounds per day
                    $roundsToday = rand(1, 2);
                    $usedRounds = [];

                    for ($r = 0; $r < $roundsToday; $r++) {
                        $availableRounds = $patrolRounds->whereNotIn('id', $usedRounds);
                        if ($availableRounds->isEmpty()) break;

                        $patrolRound = $availableRounds->random();
                        $usedRounds[] = $patrolRound->id;

                        // Create Daily Patrol Summary
                        $startTimeString = $date . ' ' . \Carbon\Carbon::parse($patrolRound->start_time)->format('H:i:s');
                        $startTime = \Carbon\Carbon::parse($startTimeString)
                            ->addMinutes(rand(-15, 30)); // Some variation in start time

                        $totalLocations = $locations->count();
                        $completedLocations = rand(floor($totalLocations * 0.6), $totalLocations); // 60-100% completion

                        $summary = DailyPatrolSummary::create([
                            'guard_id' => $guard->id,
                            'patrol_round_id' => $patrolRound->id,
                            'patrol_date' => $date,
                            'total_locations' => $totalLocations,
                            'completed_locations' => $completedLocations,
                            'missed_locations' => $totalLocations - $completedLocations,
                            'expected_start_time' => $patrolRound->start_time,
                            'expected_end_time' => $patrolRound->end_time,
                            'actual_start_time' => $startTime,
                            'actual_end_time' => $startTime->copy()->addHours(rand(2, 4)),
                            'status' => DailyPatrolSummaryStatus::COMPLETED,
                            'notes' => collect([
                                'All locations checked successfully',
                                'Minor maintenance issues noted',
                                'Routine patrol completed',
                                'Some areas required additional attention',
                                null // Some summaries without notes
                            ])->random(),
                        ]);

                        $summaryCount++;

                        // Create patrol logs for this summary
                        $locationsToPatrol = $locations->random($completedLocations);

                        foreach ($locationsToPatrol as $location) {
                            $patrolTime = $startTime->copy()->addMinutes(rand(5, 120));

                            PatrollingLog::create([
                                'location_id' => $location->id,
                                'guard_id' => $guard->id,
                                'daily_patrol_summary_id' => $summary->id,
                                'patrol_date' => $date,
                                'patrol_time' => $patrolTime,
                                'status' => collect([
                                    PatrollingStatus::CHECKED,
                                    PatrollingStatus::CHECKED,
                                    PatrollingStatus::CHECKED,
                                    PatrollingStatus::ISSUE_FOUND,
                                    PatrollingStatus::MAINTENANCE_REQUIRED
                                ])->random(), // Mostly normal, some issues
                                'notes' => $this->generatePatrolNotes(),
                                'issues_found' => rand(1, 10) <= 2 ? $this->generateIssueDescription() : null, // 20% chance of issues
                            ]);

                            $logCount++;
                        }
                    }
                }
            }
        }

        $this->command->info("Created {$summaryCount} patrol summaries and {$logCount} patrol logs for the last 30 days");
    }

    private function generateVehicleNumber(): string
    {
        $states = ['MH', 'DL', 'KA', 'TN', 'UP', 'GJ'];
        $state = collect($states)->random();
        $city = str_pad(rand(1, 99), 2, '0', STR_PAD_LEFT);
        $series = collect(['AA', 'AB', 'AC', 'AD', 'AE'])->random();
        $number = str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);

        return "{$state} {$city} {$series} {$number}";
    }

    private function generateCoordinates(): string
    {
        // Generate coordinates within a small area (simulating a residential complex)
        $baseLat = 19.0760; // Mumbai coordinates as base
        $baseLng = 72.8777;

        $lat = $baseLat + (rand(-100, 100) / 10000); // Small variation
        $lng = $baseLng + (rand(-100, 100) / 10000);

        return "{$lat},{$lng}";
    }

    private function generatePatrolNotes(): ?string
    {
        $notes = [
            'Area secure, no issues found',
            'All lights functioning properly',
            'Gate locked and secure',
            'Area clean and well-maintained',
            'Minor debris cleared',
            'Vegetation trimmed as needed',
            'No suspicious activity observed',
            'Equipment functioning normally',
            null, // Some logs without notes
            null,
        ];

        return collect($notes)->random();
    }

    private function generateIssueDescription(): string
    {
        $issues = [
            'Street light not working',
            'Garden sprinkler malfunction',
            'Parking area needs cleaning',
            'Gate hinge requires lubrication',
            'Drainage issue in common area',
            'Loose tiles near entrance',
            'Playground equipment needs inspection',
            'Pool filtration system making noise',
            'Gym equipment requires maintenance',
            'Club house AC not cooling properly'
        ];

        return collect($issues)->random();
    }
}
