<?php

namespace Modules\Inventory\Database\Seeders;

use Illuminate\Database\Seeder;
use Modules\Core\Enums\StatusEnum;
use Modules\Inventory\Enums\CategoryTypeEnum;
use Modules\Inventory\Models\Category;
use Modules\Inventory\Models\InventoryDepartment;
use Modules\Inventory\Services\CategoryService;

class CategorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $categoryService = app(CategoryService::class);

        // Fetch departments safely
        $departments = InventoryDepartment::pluck('id', 'code')->toArray();

        $required = ['PHARM', 'LABSTR', 'ASTR', 'CSTORE'];

        foreach ($required as $code) {
            if (!isset($departments[$code])) {
                throw new \Exception("Inventory Department with code {$code} not found.");
            }
        }

        // Helper function to create category and associated accounts
        $create = function (array $data) use ($categoryService) {
            $category = Category::updateOrCreate(
                ['code' => $data['code']],
                $data
            );

            $categoryService->syncAssetCategoryAccounts($category);

            return $category;
        };

        /*
        |--------------------------------------------------------------------------
        | 1. PHARMACY STORE (PHARM)
        |--------------------------------------------------------------------------
        */
        foreach ([
            ['Tablet', 'TAB'],
            ['Capsule', 'CAP'],
            ['Syrup', 'SYR'],
            ['Injection', 'INJ'],
        ] as [$name, $code]) {
            $create([
                'name' => $name,
                'code' => $code,
                'description' => "Pharmacy: {$name} medicines",
                'inventory_department_id' => $departments['PHARM'],
                'category_type' => CategoryTypeEnum::INVENTORY->value,
                'has_stock' => true,
                'has_batch' => true,
                'has_expiry' => true,
                'status' => StatusEnum::ACTIVE,
            ]);
        }

        /*
        |--------------------------------------------------------------------------
        | 2. LABORATORY STORE (LABSTR)
        |--------------------------------------------------------------------------
        */

        // Reagents & Test Kits (batch + expiry)
        foreach ([
            ['Reagents', 'REA'],
            ['Test Kits', 'TKIT'],
        ] as [$name, $code]) {
            $create([
                'name' => $name,
                'code' => $code,
                'description' => "Laboratory: {$name}",
                'inventory_department_id' => $departments['LABSTR'],
                'category_type' => CategoryTypeEnum::INVENTORY->value,
                'has_stock' => true,
                'has_batch' => true,
                'has_expiry' => true,
                'status' => StatusEnum::ACTIVE,
            ]);
        }

        // General lab consumables (no batch/expiry)
        $create([
            'name' => 'Lab Consumables',
            'code' => 'LABCON',
            'description' => 'General laboratory consumables (glassware, tubes, etc.)',
            'inventory_department_id' => $departments['LABSTR'],
            'category_type' => CategoryTypeEnum::INVENTORY->value,
            'has_stock' => true,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);

        /*
        |--------------------------------------------------------------------------
        | 3. ASSET STORE (ASTR)
        |--------------------------------------------------------------------------
        */

        $create([
            'name' => 'Medical Equipment',
            'code' => 'MEDEQP',
            'description' => 'Hospital medical equipment (X-ray, ventilators, etc.)',
            'inventory_department_id' => $departments['ASTR'],
            'category_type' => CategoryTypeEnum::ASSET->value,
            'has_stock' => false,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);

        $create([
            'name' => 'IT Equipment',
            'code' => 'ITEQP',
            'description' => 'Monitor, computers, printers, UPS, and related IT assets',
            'inventory_department_id' => $departments['ASTR'],
            'category_type' => CategoryTypeEnum::ASSET->value,
            'has_stock' => false,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);

        $create([
            'name' => 'Furniture & Fixtures',
            'code' => 'FURN',
            'description' => 'Hospital furniture and fixtures (beds, chairs, tables, cabinets, office desks)',
            'inventory_department_id' => $departments['ASTR'],
            'category_type' => CategoryTypeEnum::ASSET->value,
            'has_stock' => false,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);
        /*
        |--------------------------------------------------------------------------
        | 4. CENTRAL STORE (CSTORE)
        |--------------------------------------------------------------------------
        */

        // Medical consumables (inventory tracked)
        $create([
            'name' => 'Medical Consumables',
            'code' => 'MEDCON',
            'description' => 'Consumables used in patient care (Syringe, mask, bandage, cotton, gloves etc.)',
            'inventory_department_id' => $departments['CSTORE'],
            'category_type' => CategoryTypeEnum::INVENTORY->value,
            'has_stock' => true,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);

        // Office/operational consumables (direct expense)
        $create([
            'name' => 'Office & Cleaning Consumables',
            'code' => 'OFFCON',
            'description' => 'Office, cleaning tools, tissue, soap and operational consumables',
            'inventory_department_id' => $departments['CSTORE'],
            'category_type' => CategoryTypeEnum::EXPENSE->value,
            'has_stock' => false,
            'has_batch' => false,
            'has_expiry' => false,
            'status' => StatusEnum::ACTIVE,
        ]);
    }
}
