<?php

namespace Database\Seeders;

use App\Models\Company;
use App\Models\Department;
use App\Models\Employee;
use App\Models\User;
use App\Models\IntercompanyLoan;
use App\Models\ProfitSweepRule;
use App\Models\ProfitSweepTransaction;
use App\Models\Expense;
use App\Models\ExpenseCategory;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Carbon\Carbon;

class FullDemoSeeder extends Seeder
{
    public function run(): void
    {
        $this->seedCompanies();
        $this->seedSuperAdmin();
        $this->command->info('✅ Companies & Super Admin seeded');

        $this->seedDepartmentsAndEmployees();
        $this->command->info('✅ Departments & Employees seeded');

        $this->seedLoans();
        $this->command->info('✅ Inter-company Loans seeded');

        $this->seedProfitSweeps();
        $this->command->info('✅ Profit Sweeps seeded');

        $this->seedExpenses();
        $this->command->info('✅ Expenses seeded');

        $this->seedCompanyFinancials();
        $this->command->info('✅ Company financial fields seeded');

        $this->seedPerformanceReviews();
        $this->command->info('✅ Performance reviews seeded');

        $this->seedInvoices();
        $this->command->info('✅ Invoices seeded');

        $this->command->info('🎉 Full demo data ready!');
    }

    private function seedCompanies(): void
    {
        $companies = [
            [
                'name'               => 'Sarkin Mota Group',
                'email'              => 'group@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0001',
                'industry'           => 'Conglomerate',
                'is_holding_company' => true,
                'status'             => 'active',
                'description'        => 'The parent holding company overseeing all subsidiaries.',
                'address'            => '1 Corporate Drive, Lagos, Nigeria',
                'website'            => 'https://sarkinmotagroup.com',
            ],
            [
                'name'               => 'Sarkin Mota Tech Solutions',
                'email'              => 'tech@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0002',
                'industry'           => 'Technology',
                'is_holding_company' => false,
                'status'             => 'active',
                'description'        => 'Software development and IT services arm.',
                'address'            => '25 Silicon Valley Blvd, Lagos',
                'website'            => 'https://sarkinmotatech.com',
            ],
            [
                'name'               => 'Sarkin Mota Agro Industries',
                'email'              => 'agro@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0003',
                'industry'           => 'Agriculture',
                'is_holding_company' => false,
                'status'             => 'active',
                'description'        => 'Large-scale agricultural and food processing operations.',
                'address'            => 'Km 10, Abuja-Keffi Expressway',
                'website'            => 'https://sarkinmotaagro.com',
            ],
            [
                'name'               => 'Sarkin Mota Realty Corp',
                'email'              => 'realty@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0004',
                'industry'           => 'Real Estate',
                'is_holding_company' => false,
                'status'             => 'active',
                'description'        => 'Property development and real estate investment.',
                'address'            => '5 Marina Street, Lagos Island',
                'website'            => 'https://sarkinmotarealty.com',
            ],
            [
                'name'               => 'Sarkin Mota Logistics Ltd',
                'email'              => 'logistics@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0005',
                'industry'           => 'Logistics',
                'is_holding_company' => false,
                'status'             => 'active',
                'description'        => 'Supply chain management and freight services.',
                'address'            => 'Port Area, Apapa, Lagos',
            ],
            [
                'name'               => 'Sarkin Mota Energy Services',
                'email'              => 'energy@sarkinmotagroup.com',
                'phone'              => '+1-555-000-0006',
                'industry'           => 'Energy',
                'is_holding_company' => false,
                'status'             => 'active',
                'description'        => 'Renewable energy and power generation.',
                'address'            => '80 Aba Road, Port Harcourt',
            ],
        ];

        foreach ($companies as $data) {
            Company::firstOrCreate(['email' => $data['email']], $data);
        }
    }

    private function seedSuperAdmin(): void
    {
        $holding = Company::where('is_holding_company', true)->first();

        User::firstOrCreate(
            ['email' => 'admin@sarkinmotagroup.com'],
            [
                'name'     => 'Super Administrator',
                'password' => Hash::make('Admin@1234'),
                'company_id' => null,
            ]
        )->assignRole('Super Admin');

        // Holding company manager
        $holdingUser = User::firstOrCreate(
            ['email' => 'ceo@sarkinmotagroup.com'],
            [
                'name'       => 'CEO Group',
                'password'   => Hash::make('Holdings@1234'),
                'company_id' => $holding?->id,
            ]
        );
        try { $holdingUser->assignRole('Super Admin'); } catch (\Exception $e) {}

        // One user per subsidiary — Company Admin
        $subsidiaries = Company::where('is_holding_company', false)->get();
        foreach ($subsidiaries as $company) {
            $slug = strtolower(explode(' ', $company->name)[1] ?? 'user');
            $companyAdmin = User::firstOrCreate(
                ['email' => "admin@sarkinmota{$slug}.com"],
                [
                    'name'       => "Company Admin {$company->name}",
                    'password'   => Hash::make('CompanyAdmin@1234'),
                    'company_id' => $company->id,
                ]
            );
            try { $companyAdmin->assignRole('Company Admin'); } catch (\Exception $e) {}

            // HR Manager
            $hrManager = User::firstOrCreate(
                ['email' => "hr@sarkinmota{$slug}.com"],
                [
                    'name'       => "HR Manager {$company->name}",
                    'password'   => Hash::make('HRManager@1234'),
                    'company_id' => $company->id,
                ]
            );
            try { $hrManager->assignRole('HR Manager'); } catch (\Exception $e) {}

            // Finance Manager
            $financeManager = User::firstOrCreate(
                ['email' => "finance@sarkinmota{$slug}.com"],
                [
                    'name'       => "Finance Manager {$company->name}",
                    'password'   => Hash::make('FinanceManager@1234'),
                    'company_id' => $company->id,
                ]
            );
            try { $financeManager->assignRole('Finance Manager'); } catch (\Exception $e) {}

            // Staff users
            for ($i = 1; $i <= 3; $i++) {
                $staff = User::firstOrCreate(
                    ['email' => "staff{$i}@sarkinmota{$slug}.com"],
                    [
                        'name'       => "Staff {$i} {$company->name}",
                        'password'   => Hash::make('Staff@1234'),
                        'company_id' => $company->id,
                    ]
                );
                try { $staff->assignRole('Staff'); } catch (\Exception $e) {}
            }
        }
    }

    private function seedDepartmentsAndEmployees(): void
    {
        $companies = Company::all();

        $departmentNames = [
            'Finance & Accounting',
            'Human Resources',
            'Operations',
            'Technology & IT',
            'Sales & Marketing',
            'Legal & Compliance',
            'Customer Success',
        ];

        $positions = [
            'Senior Engineer',     'Product Manager',  'Financial Analyst',
            'HR Specialist',       'Operations Lead',  'Legal Counsel',
            'Marketing Manager',   'Data Analyst',     'Software Developer',
            'Account Manager',     'Compliance Officer','Business Developer',
            'UX Designer',         'Systems Architect','Team Lead',
        ];

        $firstNames = ['Adaeze','Chukwudi','Oluwaseun','Amara','Babatunde','Fatima',
                       'Emmanuel','Ngozi','Samuel','Kemi','Ibrahim','Blessing','John',
                       'Chisom','Taiwo','Aisha','Victor','Mercy','Obinna','Grace'];
        $lastNames  = ['Okonkwo','Adeyemi','Ibrahim','Eze','Olawale','Nwachukwu',
                       'Abubakar','Akintola','Okafor','Adebayo','Musa','Ogundipe',
                       'Chukwu','Omotola','Balogun','Lawal','Okeke','Adeleke'];

        foreach ($companies as $company) {
            $deptCount = ($company->is_holding_company) ? 3 : 4;
            $empCount  = ($company->is_holding_company) ? 15 : rand(20, 45);

            $departments = [];
            foreach (array_slice($departmentNames, 0, $deptCount) as $dname) {
                $dept = Department::firstOrCreate(
                    ['name' => $dname, 'company_id' => $company->id],
                    ['description' => "The {$dname} department of {$company->name}", 'status' => 'active']
                );
                $departments[] = $dept;
            }

            for ($i = 0; $i < $empCount; $i++) {
                $dept = $departments[array_rand($departments)];
                $firstName = $firstNames[array_rand($firstNames)];
                $lastName  = $lastNames[array_rand($lastNames)];
                $email     = strtolower("{$firstName}.{$lastName}{$i}@" . str_replace(' ', '', strtolower($company->name)) . '.com');

                $statusPool = ['active', 'active', 'active', 'active', 'on-leave', 'terminated', 'resigned'];
                Employee::firstOrCreate(
                    ['email' => $email],
                    [
                        'company_id'    => $company->id,
                        'department_id' => $dept->id,
                        'employee_id'   => 'EMP-' . strtoupper(bin2hex(random_bytes(6))),
                        'first_name'    => $firstName,
                        'last_name'     => $lastName,
                        'position'      => $positions[array_rand($positions)],
                        'employment_type' => ['full-time','part-time','contract'][rand(0,2)],
                        'status'        => $statusPool[array_rand($statusPool)],
                        'hire_date'     => Carbon::now()->subDays(rand(30, 1000)),
                        'salary'        => rand(80000, 350000),
                        'phone'         => '+234 ' . rand(700, 909) . ' ' . rand(100, 999) . ' ' . rand(1000, 9999),
                    ]
                );
            }
        }
    }

    private function seedLoans(): void
    {
        $holding     = Company::where('is_holding_company', true)->first();
        $subsidiaries = Company::where('is_holding_company', false)->get();
        if (!$holding) return;

        $loanData = [
            ['amount' => 500000,  'interest_rate' => 8.5,  'term' => 24, 'purpose' => 'Equipment procurement for production line expansion',    'status' => 'approved'],
            ['amount' => 250000,  'interest_rate' => 7.0,  'term' => 12, 'purpose' => 'Working capital for Q2 operations and payroll',          'status' => 'approved'],
            ['amount' => 1000000, 'interest_rate' => 9.0,  'term' => 36, 'purpose' => 'Real estate acquisition — Lagos Island development',     'status' => 'approved'],
            ['amount' => 150000,  'interest_rate' => 6.5,  'term' => 6,  'purpose' => 'Emergency fleet maintenance and repair',                  'status' => 'pending'],
            ['amount' => 750000,  'interest_rate' => 8.0,  'term' => 18, 'purpose' => 'Solar farm installation Phase 2',                        'status' => 'pending'],
            ['amount' => 80000,   'interest_rate' => 10.0, 'term' => 6,  'purpose' => 'IT infrastructure upgrade and cloud migration',           'status' => 'cancelled'],
        ];

        foreach ($subsidiaries->take(5) as $idx => $company) {
            $data = $loanData[$idx] ?? $loanData[0];
            IntercompanyLoan::firstOrCreate(
                [
                    'lender_company_id'   => $holding->id,
                    'borrower_company_id' => $company->id,
                    'purpose'             => $data['purpose'],
                ],
                [
                    'loan_number'       => 'LN-' . date('Y') . '-' . str_pad($idx + 1, 4, '0', STR_PAD_LEFT),
                    'principal_amount'  => $data['amount'],
                    'outstanding_balance'=> $data['amount'] * 0.85,
                    'interest_rate'     => $data['interest_rate'],
                    'interest_type'     => 'simple',
                    'term_months'       => $data['term'],
                    'payment_frequency' => 'monthly',
                    'status'            => $data['status'],
                    'disbursement_date' => Carbon::now()->subDays(rand(30, 180)),
                    'maturity_date'     => Carbon::now()->addMonths($data['term']),
                    'terms_conditions'  => 'Standard Sarkin Mota Group inter-company loan agreement.',
                ]
            );
        }
    }

    private function seedProfitSweeps(): void
    {
        $holding     = Company::where('is_holding_company', true)->first();
        $subsidiaries = Company::where('is_holding_company', false)->get();
        if (!$holding) return;

        foreach ($subsidiaries as $company) {
            $rule = ProfitSweepRule::firstOrCreate(
                ['subsidiary_id' => $company->id, 'parent_company_id' => $holding->id],
                [
                    'sweep_type'        => 'percentage',
                    'sweep_percentage'  => rand(10, 25),
                    'frequency'         => ['monthly','quarterly','annual'][rand(0,2)],
                    'threshold_amount'  => rand(10000, 50000),
                    'fixed_amount'      => null,
                    'day_of_execution'  => rand(1, 28),
                    'is_active'         => true,
                    'effective_from'    => Carbon::now()->subYear(),
                ]
            );

            // Past 6 transactions per company
            for ($i = 0; $i < 6; $i++) {
                $profit = rand(80000, 500000);
                $txNumber = 'SWEEP-' . Carbon::now()->subMonths($i)->format('Ym') . '-' . $company->id . '-' . str_pad($i + 1, 2, '0', STR_PAD_LEFT);
                ProfitSweepTransaction::firstOrCreate(
                    ['transaction_number' => $txNumber],
                    [
                        'sweep_rule_id'   => $rule->id,
                        'from_company_id' => $company->id,
                        'to_company_id'   => $holding->id,
                        'sweep_date'      => Carbon::now()->subMonths($i)->day(rand(1, 28)),
                        'subsidiary_profit' => $profit,
                        'calculated_amount' => round($profit * ($rule->sweep_percentage / 100), 2),
                        'actual_amount'     => round($profit * ($rule->sweep_percentage / 100), 2),
                        'status'           => $i === 0 ? 'pending' : 'processed',
                        'processed_at'     => $i === 0 ? null : Carbon::now()->subMonths($i)->day(rand(1, 28)),
                    ]
                );
            }
        }
    }

    private function seedExpenses(): void
    {
        $categories = [
            ['name' => 'Office Supplies',    'color' => '#1919E6'],
            ['name' => 'Travel & Transport', 'color' => '#16a34a'],
            ['name' => 'Software & Tools',   'color' => '#d97706'],
            ['name' => 'Marketing',          'color' => '#dc2626'],
            ['name' => 'Utilities',          'color' => '#7c3aed'],
            ['name' => 'Salaries',           'color' => '#0284c7'],
        ];

        $companies = Company::all();
        foreach ($categories as $cat) {
            foreach ($companies as $company) {
                $category = ExpenseCategory::firstOrCreate(
                    ['name' => $cat['name'], 'company_id' => $company->id],
                    ['color' => $cat['color'], 'is_active' => true]
                );

                for ($i = 0; $i < rand(3, 8); $i++) {
                    $expenseNumber = 'EXP-' . $company->id . '-' . $category->id . '-' . Carbon::now()->subDays($i * 5)->format('Ymd') . '-' . str_pad($i, 3, '0', STR_PAD_LEFT);
                    Expense::firstOrCreate(
                        ['expense_number' => $expenseNumber],
                        [
                            'company_id'          => $company->id,
                            'expense_category_id' => $category->id,
                            'title'               => $cat['name'] . ' — ' . Carbon::now()->subDays($i * 5)->format('M Y'),
                            'amount'              => rand(1000, 80000),
                            'expense_date'        => Carbon::now()->subDays($i * 5),
                            'status'              => ['draft','submitted','approved','rejected','paid'][rand(0,4)],
                            'description'         => "Monthly {$cat['name']} expense for {$company->name}",
                        ]
                    );
                }
            }
        }
    }

    private function seedCompanyFinancials(): void
    {
        $financials = [
            'Sarkin Mota Group'   => ['cash' => 8500000,  'assets' => 45000000, 'liabilities' => 8000000,  'health' => 'excellent', 'credit' => 820, 'runway' => 365],
            'Sarkin Mota Tech Solutions'   => ['cash' => 1200000,  'assets' => 6500000,  'liabilities' => 900000,   'health' => 'excellent', 'credit' => 790, 'runway' => 180],
            'Sarkin Mota Agro Industries'  => ['cash' => 750000,   'assets' => 4200000,  'liabilities' => 1200000,  'health' => 'good',      'credit' => 720, 'runway' => 120],
            'Sarkin Mota Realty Corp'      => ['cash' => 2100000,  'assets' => 18000000, 'liabilities' => 5500000,  'health' => 'good',      'credit' => 760, 'runway' => 200],
            'Sarkin Mota Logistics Ltd'    => ['cash' => 480000,   'assets' => 3100000,  'liabilities' => 950000,   'health' => 'fair',      'credit' => 680, 'runway' => 90],
            'Sarkin Mota Energy Services'  => ['cash' => 950000,   'assets' => 7800000,  'liabilities' => 2200000,  'health' => 'good',      'credit' => 740, 'runway' => 150],
        ];

        foreach ($financials as $name => $data) {
            Company::where('name', $name)->update([
                'cash_balance'      => $data['cash'],
                'total_assets'      => $data['assets'],
                'total_liabilities' => $data['liabilities'],
                'health_status'     => $data['health'],
                'credit_score'      => $data['credit'],
                'runway_days'       => $data['runway'],
            ]);
        }
    }

    private function seedPerformanceReviews(): void
    {
        if (!Schema::hasTable('review_cycles') || !Schema::hasTable('performance_reviews')) {
            return;
        }

        $superAdmin = User::where('email', 'admin@sarkinmotagroup.com')->first();
        if (!$superAdmin) return;

        $companies = Company::where('is_holding_company', false)->get();

        foreach ($companies as $company) {
            $cycle = DB::table('review_cycles')->where('company_id', $company->id)->first();
            if (!$cycle) {
                $cycleId = DB::table('review_cycles')->insertGetId([
                    'company_id'    => $company->id,
                    'cycle_name'    => 'Annual Review ' . date('Y'),
                    'cycle_type'    => 'annual',
                    'start_date'    => Carbon::now()->startOfYear(),
                    'end_date'      => Carbon::now()->endOfYear(),
                    'deadline_date' => Carbon::now()->endOfYear()->subMonth(),
                    'status'        => 'active',
                    'description'   => "Annual performance review cycle for {$company->name}",
                    'created_at'    => now(),
                    'updated_at'    => now(),
                ]);
            } else {
                $cycleId = $cycle->id;
            }

            $employees = Employee::where('company_id', $company->id)
                ->where('status', 'active')
                ->limit(10)
                ->get();

            foreach ($employees as $employee) {
                $exists = DB::table('performance_reviews')
                    ->where('review_cycle_id', $cycleId)
                    ->where('employee_id', $employee->id)
                    ->exists();

                if (!$exists) {
                    $rating = rand(3, 5);
                    $reviewId = DB::table('performance_reviews')->insertGetId([
                        'review_cycle_id'            => $cycleId,
                        'employee_id'                => $employee->id,
                        'reviewer_id'                => $superAdmin->id,
                        'review_date'                => Carbon::now()->subDays(rand(10, 60)),
                        'overall_rating'             => $rating,
                        'strengths'                  => 'Strong communication, reliable delivery, team player.',
                        'areas_for_improvement'      => 'Could improve time management and documentation.',
                        'goals'                      => 'Complete advanced training, lead one project independently.',
                        'reviewer_comments'          => "Overall {$rating}/5 performance. Solid contributions this cycle.",
                        'employee_comments'          => 'I agree with the assessment and will work on the identified areas.',
                        'promotion_recommended'      => $rating >= 5 ? 1 : 0,
                        'recommended_raise_percentage' => $rating >= 4 ? rand(5, 15) : rand(0, 5),
                        'status'                     => ['submitted', 'acknowledged'][rand(0,1)],
                        'submitted_at'               => Carbon::now()->subDays(rand(5, 30)),
                        'acknowledged_at'            => Carbon::now()->subDays(rand(1, 5)),
                        'created_at'                 => now(),
                        'updated_at'                 => now(),
                    ]);

                    $competencies = ['Communication','Leadership','Technical Skills','Problem Solving','Teamwork','Initiative'];
                    foreach ($competencies as $comp) {
                        DB::table('review_competencies')->insert([
                            'performance_review_id' => $reviewId,
                            'competency_name'       => $comp,
                            'rating'                => rand(3, 5),
                            'comments'              => "Good performance in {$comp}.",
                            'created_at'            => now(),
                            'updated_at'            => now(),
                        ]);
                    }
                }
            }
        }
    }

    private function seedInvoices(): void
    {
        if (!Schema::hasTable('invoices')) return;

        $companies  = Company::all();
        $statuses   = ['paid','paid','paid','issued','overdue','draft','cancelled'];
        $items = 0;

        foreach ($companies as $company) {
            for ($m = 5; $m >= 0; $m--) {
                $invoiceDate = Carbon::now()->subMonths($m)->startOfMonth()->addDays(rand(1, 10));
                $dueDate     = $invoiceDate->copy()->addDays(30);
                $status      = $statuses[array_rand($statuses)];
                $amount      = rand(50000, 400000);
                $invNumber   = 'INV-' . $company->id . '-' . $invoiceDate->format('Ym') . '-' . str_pad(rand(1,99), 3, '0', STR_PAD_LEFT);

                $exists = DB::table('invoices')->where('invoice_number', $invNumber)->exists();
                if ($exists) continue;

                try {
                    DB::table('invoices')->insert([
                        'company_id'     => $company->id,
                        'invoice_number' => $invNumber,
                        'invoice_date'   => $invoiceDate,
                        'due_date'       => $dueDate,
                        'total_amount'   => $amount,
                        'status'         => $status,
                        'created_at'     => now(),
                        'updated_at'     => now(),
                    ]);
                    $items++;
                } catch (\Exception $e) {
                    // Column mismatch — skip
                }
            }
        }

        if ($items > 0) $this->command->info("  → {$items} invoices inserted");
    }
}
