<?php

namespace App\Database\Seeds;

use App\Core\Modules\Services\ModuleManager;
use CodeIgniter\Database\Seeder;

class CoreSeeder extends Seeder
{
    public function run(): void
    {
        $this->permissions();
        $this->roles();
        $this->rolePermissions();
        $this->adminUser();
        $this->settings();
        $this->license();
        (new ModuleManager())->sync();
    }

    private function permissions(): void
    {
        $permissions = [
            ['name' => 'core.dashboard.view', 'label' => 'Voir le dashboard', 'group_name' => 'Core'],
            ['name' => 'core.users.manage', 'label' => 'Gérer les utilisateurs', 'group_name' => 'Core'],
            ['name' => 'core.roles.manage', 'label' => 'Gérer les rôles', 'group_name' => 'Core'],
            ['name' => 'core.settings.manage', 'label' => 'Gérer les paramètres', 'group_name' => 'Core'],
            ['name' => 'core.ai.use', 'label' => 'Utiliser le moteur IA', 'group_name' => 'Core'],
            ['name' => 'core.exports.use', 'label' => 'Utiliser les exports', 'group_name' => 'Core'],
            ['name' => 'core.audit.view', 'label' => 'Voir le journal d’audit', 'group_name' => 'Core'],
            ['name' => 'core.modules.manage', 'label' => 'Gérer les modules', 'group_name' => 'Core'],
            ['name' => 'core.database.manage', 'label' => 'Gérer les connexions SQL', 'group_name' => 'Core'],
        ];

        foreach ($permissions as $permission) {
            $this->db->table('core_permissions')->ignore(true)->insert($permission + [
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }
    }

    private function roles(): void
    {
        $roles = [
            ['name' => 'super_admin', 'label' => 'Super Admin'],
            ['name' => 'admin', 'label' => 'Admin'],
            ['name' => 'reader', 'label' => 'Lecture seule'],
        ];

        foreach ($roles as $role) {
            $this->db->table('core_roles')->ignore(true)->insert($role + [
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }
    }

    private function rolePermissions(): void
    {
        $roles = $this->db->table('core_roles')->get()->getResultArray();
        $permissions = $this->db->table('core_permissions')->get()->getResultArray();
        $permissionIdsByName = array_column($permissions, 'id', 'name');

        $grants = [
            'super_admin' => array_keys($permissionIdsByName),
            'admin' => [
                'core.dashboard.view',
                'core.users.manage',
                'core.roles.manage',
                'core.settings.manage',
                'core.modules.manage',
                'core.database.manage',
                'core.ai.use',
                'core.exports.use',
                'core.audit.view',
            ],
            'reader' => [
                'core.dashboard.view',
            ],
        ];

        foreach ($roles as $role) {
            foreach ($grants[$role['name']] ?? [] as $permissionName) {
                if (! isset($permissionIdsByName[$permissionName])) {
                    continue;
                }

                $this->db->table('core_role_permissions')->ignore(true)->insert([
                    'role_id' => $role['id'],
                    'permission_id' => $permissionIdsByName[$permissionName],
                ]);
            }
        }
    }

    private function adminUser(): void
    {
        $email = (string) (env('admin.seed_email') ?: 'admin@one-core.local');
        $password = (string) (env('admin.seed_password') ?: 'ChangeMe123!');

        $existing = $this->db->table('core_users')->where('email', $email)->get()->getRowArray();
        if (! $existing) {
            $this->db->table('core_users')->insert([
                'email' => $email,
                'password_hash' => password_hash($password, PASSWORD_DEFAULT),
                'firstname' => 'Admin',
                'lastname' => 'ONE CORE',
                'status' => 'active',
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
            $userId = $this->db->insertID();
        } else {
            $userId = $existing['id'];
        }

        $role = $this->db->table('core_roles')->where('name', 'super_admin')->get()->getRowArray();
        $this->db->table('core_user_roles')->ignore(true)->insert([
            'user_id' => $userId,
            'role_id' => $role['id'],
        ]);
    }

    private function settings(): void
    {
        $settings = [
            ['setting_key' => 'app.name', 'setting_value' => 'ONE CORE', 'setting_group' => 'general', 'is_encrypted' => 0],
            ['setting_key' => 'app.logo', 'setting_value' => '', 'setting_group' => 'theme', 'is_encrypted' => 0],
            ['setting_key' => 'app.theme', 'setting_value' => 'default', 'setting_group' => 'theme', 'is_encrypted' => 0],
            ['setting_key' => 'openai.api_key', 'setting_value' => '', 'setting_group' => 'ai', 'is_encrypted' => 1],
            ['setting_key' => 'openai.model', 'setting_value' => 'gpt-4.1-mini', 'setting_group' => 'ai', 'is_encrypted' => 0],
            ['setting_key' => 'admin.email', 'setting_value' => (string) (env('admin.seed_email') ?: 'admin@one-core.local'), 'setting_group' => 'email', 'is_encrypted' => 0],
            ['setting_key' => 'app.maintenance', 'setting_value' => '0', 'setting_group' => 'general', 'is_encrypted' => 0],
            ['setting_key' => 'app.language', 'setting_value' => 'fr', 'setting_group' => 'general', 'is_encrypted' => 0],
            ['setting_key' => 'app.timezone', 'setting_value' => 'Europe/Paris', 'setting_group' => 'general', 'is_encrypted' => 0],
        ];

        foreach ($settings as $setting) {
            $this->db->table('core_settings')->ignore(true)->insert($setting + [
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }
    }

    private function license(): void
    {
        $existing = $this->db->table('core_license')->countAllResults();
        if ($existing > 0) {
            return;
        }

        $this->db->table('core_license')->insert([
            'license_key' => 'ONE-CORE-FREE',
            'product' => 'one-core',
            'plan' => 'free',
            'status' => 'active',
            'domain' => null,
            'expires_at' => null,
            'max_users' => 3,
            'max_modules' => 10,
            'max_ai_requests_month' => 100,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
    }
}
