<?php

namespace Database\Seeders;

use App\Models\Branch;
use App\Models\HealthVisit;
use App\Models\Incident;
use App\Models\InventoryItem;
use App\Models\Invitation;
use App\Models\MessageCampaign;
use App\Models\PayrollRun;
use App\Models\Payslip;
use App\Models\Staff;
use App\Models\StockMovement;
use App\Models\Student;
use App\Models\User;
use App\Models\Visitor;
use App\Models\DailyPlan;
use Illuminate\Database\Seeder;
use Illuminate\Support\Carbon;

/**
 * Populates modules that otherwise ship empty so every screen demos with
 * data: family/visitor log, clinic (health) visits, incidents, event
 * invitations, a payroll run with payslips, a message campaign, inventory
 * stock movements and a few daily plans. Idempotent — each block only seeds
 * when the table is (near) empty.
 */
class EmptyModulesSeeder extends Seeder
{
    public function run(): void
    {
        $branch = Branch::orderBy('id')->first();
        $branchId = $branch?->id;

        $this->seedVisitors();
        $this->seedHealthVisits();
        $this->seedIncidents($branchId);
        $this->seedInvitations($branchId);
        $this->seedDailyPlans($branchId);
        $this->seedPayroll();
        $this->seedCampaigns();
        $this->seedStockMovements();

        $this->command?->info('Empty-module demo data seeded.');
    }

    /** Family / general visitor log. */
    private function seedVisitors(): void
    {
        if (Visitor::count() >= 6) {
            return;
        }
        $rows = [
            ['Abdul Ghafoor', 'Meet class teacher (Grade 3 - A)', 'Ms. Fatima'],
            ['Nasima Rahimi', 'Fee inquiry for two children', 'Accounts Office'],
            ['Haji Karim', 'Parent–teacher meeting', 'Principal'],
            ['Zahra Mother', 'Collect result card', 'Reception'],
            ['Wakil Ahmad', 'Discuss son\'s attendance', 'Deputy Head'],
            ['Gul Makai', 'Admission enquiry (new sibling)', 'Admissions'],
        ];
        foreach ($rows as $i => [$name, $purpose, $toMeet]) {
            $in = Carbon::now()->subDays($i)->setTime(8 + $i, 15);
            Visitor::create([
                'name' => $name,
                'phone' => '07' . str_pad((string) (10000000 + $i * 137), 8, '0', STR_PAD_LEFT),
                'purpose' => $purpose,
                'to_meet' => $toMeet,
                'check_in' => $in,
                'check_out' => $i % 3 === 0 ? null : (clone $in)->addMinutes(35),
                'pass_no' => 'V-' . str_pad((string) ($i + 1), 4, '0', STR_PAD_LEFT),
            ]);
        }
    }

    /** School clinic visits. */
    private function seedHealthVisits(): void
    {
        if (HealthVisit::count() >= 6) {
            return;
        }
        $names = Student::inRandomOrder()->limit(6)->pluck('first_name', 'id');
        $cases = [
            ['Headache and mild fever', 'Rest, paracetamol, informed family', 'Nurse Halima'],
            ['Minor cut on knee', 'Cleaned and dressed the wound', 'Nurse Halima'],
            ['Stomach ache', 'Given ORS, observed for 30 min', 'Dr. Sayed'],
            ['Nose bleed', 'First aid applied, settled', 'Nurse Halima'],
            ['Toothache', 'Advised dental check-up', 'Dr. Sayed'],
            ['Allergy / rash', 'Antihistamine, family informed', 'Nurse Halima'],
        ];
        $i = 0;
        foreach ($names as $name) {
            [$complaint, $treatment, $by] = $cases[$i % count($cases)];
            HealthVisit::create([
                'student_name' => $name,
                'date' => Carbon::now()->subDays($i * 2)->toDateString(),
                'complaint' => $complaint,
                'treatment' => $treatment,
                'given_by' => $by,
                'note' => null,
            ]);
            $i++;
        }
    }

    private function seedIncidents(?int $branchId): void
    {
        if (Incident::count() >= 5) {
            return;
        }
        $rows = [
            ['student', 'Late arrival (repeated)', 'discipline', 'low', 'Verbal warning, family notified', 'resolved'],
            ['student', 'Damaged classroom property', 'property', 'medium', 'Parent asked to cover cost', 'open'],
            ['student', 'Fight during break', 'discipline', 'high', 'Counselling + parent meeting', 'open'],
            ['staff', 'Slippery corridor near lab', 'safety', 'medium', 'Wet-floor sign placed, cleaned', 'resolved'],
            ['student', 'Fainted in assembly (heat)', 'health', 'medium', 'Moved to clinic, recovered', 'resolved'],
        ];
        foreach ($rows as $i => [$pt, $name, $cat, $sev, $action, $status]) {
            Incident::create([
                'branch_id' => $branchId,
                'person_type' => $pt,
                'person_name' => $name === '' ? null : 'Reported case #' . ($i + 1),
                'category' => $cat,
                'severity' => $sev,
                'date' => Carbon::now()->subDays($i * 3)->toDateString(),
                'description' => $name,
                'action_taken' => $action,
                'status' => $status,
                'reported_by' => 'Duty Teacher',
            ]);
        }
    }

    private function seedInvitations(?int $branchId): void
    {
        if (Invitation::count() >= 2) {
            return;
        }
        $rows = [
            ['Annual Prize Distribution 1404', 'Prize Day', '+20 days', '09:00', 'Main Hall', 'Parents & Students', 'Governor of the Province'],
            ['Parent–Teacher Conference', 'PTM', '+7 days', '13:30', 'Class blocks', 'All Parents', null],
            ['Science & Book Fair', 'Exhibition', '+35 days', '08:30', 'School Ground', 'Community', 'District Education Head'],
        ];
        foreach ($rows as [$title, $occasion, $rel, $time, $venue, $audience, $guest]) {
            Invitation::create([
                'branch_id' => $branchId,
                'title' => $title,
                'occasion' => $occasion,
                'event_date' => Carbon::now()->modify($rel)->toDateString(),
                'event_time' => $time,
                'venue' => $venue,
                'audience' => $audience,
                'chief_guest' => $guest,
                'body' => "You are cordially invited to the {$title}. Your presence will honour the occasion.",
                'rsvp' => null,
                'status' => 'draft',
            ]);
        }
    }

    private function seedDailyPlans(?int $branchId): void
    {
        if (DailyPlan::count() >= 4) {
            return;
        }
        $user = User::orderBy('id')->first();
        $rows = [
            ['Review Grade 7 monthly evaluations', 'evaluation', 'high', 0, 'pending'],
            ['Approve pending fee waivers', 'finance', 'normal', 0, 'pending'],
            ['Walk-through of science lab safety', 'admin', 'normal', -1, 'done'],
            ['Call families of absent students', 'communication', 'high', 0, 'pending'],
            ['Prepare weekly staff meeting agenda', 'admin', 'low', 1, 'pending'],
        ];
        foreach ($rows as [$title, $cat, $prio, $dayOff, $status]) {
            DailyPlan::create([
                'branch_id' => $branchId,
                'user_id' => $user?->id,
                'assigned_by' => $user?->id,
                'role' => $user?->role ?? 'manager',
                'title' => $title,
                'description' => null,
                'plan_date' => Carbon::now()->addDays($dayOff)->toDateString(),
                'due_time' => '15:00',
                'category' => $cat,
                'priority' => $prio,
                'status' => $status,
                'done_at' => $status === 'done' ? Carbon::now()->subDay() : null,
            ]);
        }
    }

    private function seedPayroll(): void
    {
        if (PayrollRun::count() >= 1) {
            return;
        }
        $staff = Staff::orderBy('id')->limit(25)->get();
        if ($staff->isEmpty()) {
            return;
        }
        $period = Carbon::now()->subMonthNoOverflow()->format('Y-m');
        $run = PayrollRun::create([
            'period' => $period,
            'run_date' => Carbon::now()->subMonthNoOverflow()->endOfMonth()->toDateString(),
            'total_gross' => 0,
            'total_deductions' => 0,
            'total_net' => 0,
            'status' => 'finalized',
            'created_by' => User::value('id'),
        ]);
        $gross = $ded = $net = 0;
        foreach ($staff as $i => $s) {
            $basic = (float) ($s->basic_salary ?: 12000 + ($i % 6) * 1500);
            $absence = $i % 5 === 0 ? 1 : 0;
            $deductions = round($basic / 30 * $absence, 2);
            $bonus = $i % 7 === 0 ? 1000 : 0;
            $payNet = round($basic - $deductions + $bonus, 2);
            Payslip::create([
                'payroll_run_id' => $run->id,
                'staff_id' => $s->id,
                'basic' => $basic,
                'absence_days' => $absence,
                'deductions' => $deductions,
                'bonus' => $bonus,
                'net' => $payNet,
                'status' => 'paid',
            ]);
            $gross += $basic + $bonus;
            $ded += $deductions;
            $net += $payNet;
        }
        $run->update(['total_gross' => $gross, 'total_deductions' => $ded, 'total_net' => $net]);
    }

    private function seedCampaigns(): void
    {
        if (MessageCampaign::count() >= 2) {
            return;
        }
        $rows = [
            ['Monthly evaluation results to families', 'families', 'sent', 380, 372, 8],
            ['Prize Day invitation broadcast', 'families', 'draft', 0, 0, 0],
        ];
        foreach ($rows as [$title, $audience, $status, $total, $sent, $failed]) {
            MessageCampaign::create([
                'title' => $title,
                'template_id' => null,
                'body' => 'محترم والدین، ' . $title,
                'audience' => $audience,
                'language' => 'fa',
                'status' => $status,
                'total' => $total,
                'sent_count' => $sent,
                'failed_count' => $failed,
                'created_by' => User::value('id'),
                'sent_at' => $status === 'sent' ? Carbon::now()->subDays(3) : null,
            ]);
        }
    }

    private function seedStockMovements(): void
    {
        if (StockMovement::count() >= 5) {
            return;
        }
        $items = InventoryItem::orderBy('id')->limit(6)->get();
        if ($items->isEmpty()) {
            return;
        }
        foreach ($items as $i => $item) {
            StockMovement::create([
                'item_id' => $item->id,
                'type' => 'in',
                'quantity' => 20 + $i * 5,
                'date' => Carbon::now()->subDays(14 - $i)->toDateString(),
                'person' => 'Store Keeper',
                'note' => 'Opening / restock',
            ]);
            StockMovement::create([
                'item_id' => $item->id,
                'type' => 'out',
                'quantity' => 3 + $i,
                'date' => Carbon::now()->subDays(7 - min($i, 6))->toDateString(),
                'person' => 'Class ' . (($i % 6) + 1),
                'note' => 'Issued to classroom',
            ]);
        }
    }
}
