<?php

namespace Database\Seeders;

use App\Models\Branch;
use App\Models\CompanyProfile;
use App\Models\DocumentSequence;
use App\Models\FinancialYear;
use App\Models\GeneralSetting;
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use App\Models\VatSetting;
use App\Models\Warehouse;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        // 1. Create Modules and Permissions
        $modules = [
            'Dashboard', 'Products', 'Categories', 'Units', 'Customers', 'Suppliers',
            'Sales', 'Sales Return', 'Purchases', 'Purchase Return', 'Inventory',
            'Warehouses', 'Stock Adjustment', 'Stock Transfer', 'Accounts', 'Journal',
            'Cash', 'Bank', 'Receipts', 'Payments', 'Expenses', 'VAT', 'Reports',
            'Van Sales', 'Backups', 'Users', 'Roles', 'Settings', 'Audit Logs'
        ];

        $actions = [
            'view' => 'View',
            'create' => 'Create',
            'edit' => 'Edit',
            'delete' => 'Delete',
            'approve' => 'Approve',
            'cancel' => 'Cancel',
            'print' => 'Print',
            'export' => 'Export',
            'view_cost' => 'View Cost',
            'view_profit' => 'View Profit',
            'view_reports' => 'View Reports',
            'view_all_branches' => 'View All Branches',
            'view_own_branch' => 'View Own Branch',
            'change_price' => 'Change Price',
            'give_discount' => 'Give Discount',
            'change_vat' => 'Change VAT',
            'backdate_transaction' => 'Backdate Transaction',
            'reprint_invoice' => 'Reprint Invoice',
            'edit_finalized' => 'Edit Finalized Transaction',
            'access_settings' => 'Access Settings',
        ];

        $allPermissionIds = [];
        foreach ($modules as $module) {
            foreach ($actions as $actKey => $actName) {
                $slug = Str::slug($module) . '.' . $actKey;
                $name = $actName . ' ' . $module;
                $perm = Permission::firstOrCreate(
                    ['slug' => $slug],
                    ['name' => $name, 'module' => $module]
                );
                $allPermissionIds[] = $perm->id;
            }
        }

        // 2. Default Roles
        $rolesData = [
            ['name' => 'Super Admin', 'slug' => 'super-admin', 'is_system' => true],
            ['name' => 'Company Admin / Owner', 'slug' => 'company-admin', 'is_system' => true],
            ['name' => 'Accountant', 'slug' => 'accountant', 'is_system' => true],
            ['name' => 'Cashier', 'slug' => 'cashier', 'is_system' => true],
            ['name' => 'Sales User', 'slug' => 'sales-user', 'is_system' => true],
            ['name' => 'Purchase User', 'slug' => 'purchase-user', 'is_system' => true],
            ['name' => 'Storekeeper', 'slug' => 'storekeeper', 'is_system' => true],
            ['name' => 'Van Salesman', 'slug' => 'van-salesman', 'is_system' => true],
            ['name' => 'Van Supervisor', 'slug' => 'van-supervisor', 'is_system' => true],
            ['name' => 'Auditor', 'slug' => 'auditor', 'is_system' => true],
        ];

        foreach ($rolesData as $rData) {
            $role = Role::firstOrCreate(['slug' => $rData['slug']], $rData);
            if ($role->slug === 'super-admin' || $role->slug === 'company-admin') {
                $role->permissions()->sync($allPermissionIds);
            }
        }

        // Sensible least-privilege defaults; administrators retain the full matrix.
        $roleModules = [
            'accountant' => ['Dashboard', 'Products', 'Customers', 'Suppliers', 'Sales', 'Sales Return', 'Purchases', 'Purchase Return', 'Inventory', 'Accounts', 'Journal', 'Cash', 'Bank', 'Receipts', 'Payments', 'Expenses', 'VAT', 'Reports', 'Audit Logs'],
            'cashier' => ['Dashboard', 'Products', 'Customers', 'Sales', 'Receipts'],
            'sales-user' => ['Dashboard', 'Products', 'Customers', 'Sales', 'Sales Return', 'Receipts'],
            'purchase-user' => ['Dashboard', 'Products', 'Suppliers', 'Purchases', 'Purchase Return'],
            'storekeeper' => ['Dashboard', 'Products', 'Categories', 'Units', 'Inventory', 'Warehouses', 'Stock Adjustment', 'Stock Transfer'],
            'van-salesman' => ['Dashboard', 'Products', 'Customers', 'Sales', 'Sales Return', 'Inventory', 'Receipts', 'Van Sales'],
            'van-supervisor' => ['Dashboard', 'Products', 'Customers', 'Sales', 'Sales Return', 'Inventory', 'Warehouses', 'Stock Transfer', 'Receipts', 'Van Sales', 'Reports'],
        ];
        $roleActions = [
            'accountant' => ['view', 'create', 'edit', 'approve', 'print', 'export', 'view_cost', 'view_profit', 'view_reports', 'view_all_branches'],
            'cashier' => ['view', 'create', 'approve', 'print', 'reprint_invoice', 'give_discount', 'view_own_branch'],
            'sales-user' => ['view', 'create', 'approve', 'print', 'reprint_invoice', 'give_discount', 'view_own_branch'],
            'purchase-user' => ['view', 'create', 'edit', 'approve', 'print', 'export', 'view_cost', 'view_own_branch'],
            'storekeeper' => ['view', 'create', 'edit', 'approve', 'print', 'export', 'view_cost', 'view_own_branch'],
            'van-salesman' => ['view', 'create', 'approve', 'print', 'reprint_invoice', 'give_discount', 'view_own_branch'],
            'van-supervisor' => ['view', 'create', 'edit', 'approve', 'print', 'export', 'view_cost', 'view_profit', 'view_reports', 'view_all_branches'],
        ];
        foreach ($roleModules as $roleSlug => $moduleNames) {
            $role = Role::where('slug', $roleSlug)->first();
            $actions = $roleActions[$roleSlug];
            $ids = Permission::whereIn('module', $moduleNames)->get()
                ->filter(fn ($permission) => collect($actions)->contains(fn ($action) => str_ends_with($permission->slug, '.'.$action)))
                ->pluck('id');
            $role?->permissions()->sync($ids);
        }
        $auditor = Role::where('slug', 'auditor')->first();
        $auditorPermissionIds = Permission::all()
            ->filter(fn ($permission) => preg_match('/\.(view|print|export|view_cost|view_profit|view_reports|view_all_branches|view_own_branch)$/', $permission->slug))
            ->pluck('id');
        $auditor?->permissions()->sync($auditorPermissionIds);

        // 3. Super Admin User
        $admin = User::updateOrCreate(
            ['email' => 'admin@saudierp.com'],
            [
                'name' => 'System Admin',
                'username' => 'admin',
                'email' => 'admin@saudierp.com',
                'phone' => '+966500000000',
                'password' => Hash::make('Password123!'),
                'status' => 'active',
                'is_super_admin' => true,
                'language' => 'en',
            ]
        );
        $superAdminRole = Role::where('slug', 'super-admin')->first();
        if ($superAdminRole) {
            $admin->roles()->sync([$superAdminRole->id]);
        }

        // 4. Default Company Profile & VAT
        CompanyProfile::getProfile();
        VatSetting::getSettings();
        GeneralSetting::getSettings();

        // 5. Default Branch
        $branch = Branch::firstOrCreate(
            ['code' => 'JED'],
            [
                'name_en' => 'Jeddah Main Branch',
                'name_ar' => 'فرع جدة الرئيسي',
                'cr_number' => '1010123456',
                'phone' => '+966 12 600 0000',
                'email' => 'jeddah@saudierp.com',
                'building_number' => '1234',
                'street_name' => 'Al Hamra Street',
                'district' => 'Al Hamra',
                'city' => 'Jeddah',
                'postal_code' => '21511',
                'manager_name' => 'Mutlaq Sati',
                'invoice_prefix' => 'JED',
                'status' => 'active',
            ]
        );

        $admin->branches()->sync([$branch->id]);

        // 6. Default Warehouses
        $whMain = Warehouse::firstOrCreate(
            ['code' => 'WH-001'],
            [
                'name_en' => 'Main Warehouse',
                'name_ar' => 'المستودع الرئيسي',
                'branch_id' => $branch->id,
                'type' => 'main',
                'contact_person' => 'Storekeeper Ahmed',
                'phone' => '+966551234567',
                'status' => 'active',
            ]
        );

        Warehouse::firstOrCreate(
            ['code' => 'VAN-001'],
            [
                'name_en' => 'Van 01 Warehouse',
                'name_ar' => 'مستودع الفان 01',
                'branch_id' => $branch->id,
                'type' => 'van',
                'contact_person' => 'Van Salesman Ali',
                'phone' => '+966559876543',
                'status' => 'active',
            ]
        );

        $branch->update(['default_warehouse_id' => $whMain->id]);

        // 7. Financial Year
        FinancialYear::firstOrCreate(
            ['name' => 'FY 2026'],
            [
                'start_date' => '2026-01-01',
                'end_date' => '2026-12-31',
                'status' => 'open',
                'is_default' => true,
            ]
        );

        // 8. Document Sequences
        $sequences = [
            ['sequence_type' => 'sales_invoice', 'prefix' => 'INV', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'simplified_tax_invoice', 'prefix' => 'SI', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'sales_return', 'prefix' => 'SRN', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'purchase_invoice', 'prefix' => 'PUR', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'receipt', 'prefix' => 'REC', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'payment', 'prefix' => 'PAY', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
            ['sequence_type' => 'journal', 'prefix' => 'JRN', 'starting_number' => 1, 'next_number' => 1, 'digit_length' => 6],
        ];

        foreach ($sequences as $seq) {
            DocumentSequence::firstOrCreate(
                ['sequence_type' => $seq['sequence_type']],
                $seq
            );
        }

        $this->call(Prompt2Seeder::class);
        $this->call(ErpSeeder::class);
    }
}
