<?php

namespace Database\Seeders;

use App\Models\User;
use App\Models\Client;
use App\Models\Session;
use App\Models\Conveyance;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class PastSessionsWithDataSeeder extends Seeder
{
    public function run(): void
    {
        DB::transaction(function () {

            // 1) Determine base start year from active session or today
            $active = Session::where('is_active', true)->first();

            if ($active) {
                $baseStartYear = Carbon::parse($active->start_date)->year;
            } else {
                $today = Carbon::today();
                $baseStartYear = ($today->month >= 4) ? $today->year : ($today->year - 1);
            }

            // 2) Prepare two previous sessions (names like "2023-2024")
            $sessionsToCreate = [];
            for ($i = 1; $i <= 2; $i++) {
                $startYear = $baseStartYear - $i;
                $endYear = $startYear + 1;
                $name = "{$startYear}-{$endYear}";

                $sessionsToCreate[] = [
                    'name' => $name,
                    'start_date' => "{$startYear}-04-01",
                    'end_date'   => "{$endYear}-03-31",
                ];
            }

            // 3) Fetch existing employees & clients (do NOT create new ones)
            $employees = User::where('role', 'employee')->get();
            $clients   = Client::all();

            if ($employees->isEmpty() || $clients->isEmpty()) {
                // If either is empty, we still create sessions but skip conveyance insertion.
                // You can remove this guard if you prefer an exception instead.
            }

            // 4) Create sessions & insert small conveyance data using existing employees/clients
            foreach ($sessionsToCreate as $sData) {
                $session = Session::firstOrCreate(
                    ['name' => $sData['name']],
                    [
                        'start_date' => $sData['start_date'],
                        'end_date'   => $sData['end_date'],
                        'is_active'  => false,
                    ]
                );

                // Ensure proper dates set if session existed with different values
                if ($session->start_date->toDateString() !== $sData['start_date']
                    || $session->end_date->toDateString() !== $sData['end_date']) {
                    $session->update([
                        'start_date' => $sData['start_date'],
                        'end_date'   => $sData['end_date'],
                        'is_active'  => false,
                    ]);
                }

                // Skip conveyance creation if no employees/clients available
                if ($employees->isEmpty() || $clients->isEmpty()) {
                    continue;
                }

                // Choose a single representative month inside session for lightweight data (start + 3 months or start)
                $sessionStart = Carbon::parse($session->start_date);
                $sessionEnd   = Carbon::parse($session->end_date);
                $targetMonth = $sessionStart->copy()->addMonthsNoOverflow(3);
                if ($targetMonth->greaterThan($sessionEnd)) {
                    $targetMonth = $sessionStart->copy();
                }

                $monthStart = $targetMonth->copy()->startOfMonth();
                $monthEnd   = $targetMonth->copy()->endOfMonth();
                $period = CarbonPeriod::create($monthStart, $monthEnd)->toArray();

                $modes = ['Auto', 'Cab', 'Metro', 'Bus'];
                $fromLocations = ['Home', 'PAC Office', 'Client Site', 'Branch Office'];
                $toLocations   = ['PAC Office', 'Client Site', 'Branch Office', 'Home'];

                $insertRows = [];

                // For each employee create a few random trips in that month
                foreach ($employees as $emp) {
                    // pick 3-5 random days from the month
                    if (empty($period)) {
                        continue;
                    }

                    $days = $period;
                    shuffle($days);
                    $daysToUse = array_slice($days, 0, rand(3, 5));

                    foreach ($daysToUse as $date) {
                        $tripCount = rand(0, 2); // 0-2 trips that day
                        for ($t = 0; $t < $tripCount; $t++) {
                            $client = $clients->random();
                            $mode   = $modes[array_rand($modes)];
                            $from   = $fromLocations[array_rand($fromLocations)];
                            $to     = $toLocations[array_rand($toLocations)];
                            $amount = rand(60, 450);
                            $isReturn = rand(0, 1) === 1;
                            $returnAmount = $isReturn ? $amount : null;
                            $status = (rand(1, 100) <= 85) ? 'submitted' : 'draft';

                            $insertRows[] = [
                                'user_id'        => $emp->id,
                                'session_id'     => $session->id,
                                'date'           => $date->toDateString(),
                                'from_location'  => $from,
                                'to_location'    => $to,
                                'client_id'      => $client->id,
                                'mode'           => $mode,
                                'amount'         => $amount,
                                'remarks'        => 'Seeded (past session)',
                                'is_return'      => $isReturn,
                                'return_amount'  => $returnAmount,
                                'return_remarks' => $isReturn ? 'Return same as onward (seed)' : null,
                                'status'         => $status,
                                'created_at'     => now(),
                                'updated_at'     => now(),
                            ];
                        }
                    }
                }

                // Bulk insert (safe for small amounts)
                if (!empty($insertRows)) {
                    $chunks = array_chunk($insertRows, 500);
                    foreach ($chunks as $chunk) {
                        Conveyance::insert($chunk);
                    }
                }
            } // end foreach sessions
        }); // end transaction
    }
}
