<?php

namespace App\Database\Seeds;

use CodeIgniter\Database\Seeder;

class MasterSeeder extends Seeder
{
    /**
     * Seeds core RBAC data, default settings, and the initial permission set.
     * Subscription plans / credit costs are seeded separately by
     * BillingSeeder (Phase 4) to keep this seeder focused on Phase 1 scope.
     */
    public function run(): void
    {
        $this->seedRoles();
        $this->seedPermissions();
        $this->seedDefaultSettings();
    }

    private function seedRoles(): void
    {
        $roles = [
            ['name' => 'Super Admin',   'slug' => 'super_admin',   'description' => 'Platform owner, full access'],
            ['name' => 'Agency Owner',  'slug' => 'agency_owner',  'description' => 'Owns an agency tenant'],
            ['name' => 'Recruiter',     'slug' => 'recruiter',     'description' => 'Agency staff member'],
            ['name' => 'Candidate',     'slug' => 'candidate',     'description' => 'Job seeker'],
            ['name' => 'Support Staff', 'slug' => 'support_staff', 'description' => 'Optional agency support role'],
        ];

        foreach ($roles as $role) {
            $exists = $this->db->table('roles')->where('slug', $role['slug'])->get()->getRow();
            if (! $exists) {
                $role['created_at'] = date('Y-m-d H:i:s');
                $role['updated_at'] = date('Y-m-d H:i:s');
                $this->db->table('roles')->insert($role);
            }
        }
    }

    private function seedPermissions(): void
    {
        // module => [action, action, ...]  — expanded as later phases add modules.
        // This is the Phase 1–3 baseline matching 04-roles-permissions-matrix.md
        $modules = [
            'agencies'    => ['view_all', 'verify', 'suspend', 'edit_own'],
            'recruiters'  => ['invite', 'remove', 'set_permissions', 'view_activity'],
            'jobs'        => ['create', 'edit', 'delete', 'publish', 'feature', 'view'],
            'candidates'  => ['search', 'contact_reveal', 'resume_download', 'unlock_profile', 'tag', 'save'],
            'applications'=> ['view', 'change_status', 'assign_recruiter', 'apply'],
            'interviews'  => ['schedule', 'reschedule', 'cancel', 'feedback'],
            'messaging'   => ['send'],
            'billing'     => ['manage_plan', 'manage_payment_methods', 'purchase_credits', 'view_invoices', 'request_refund'],
            'reports'     => ['platform_wide', 'agency_scoped'],
            'settings'    => ['global', 'agency_scoped'],
            'audit'       => ['view_platform', 'view_agency'],
            'reviews'     => ['moderate', 'submit'],
        ];

        $rolePermissionMap = $this->rolePermissionDefaults();

        foreach ($modules as $module => $actions) {
            foreach ($actions as $action) {
                $slug = "{$module}.{$action}";
                $exists = $this->db->table('permissions')->where('slug', $slug)->get()->getRow();
                if (! $exists) {
                    $this->db->table('permissions')->insert([
                        'module'     => $module,
                        'name'       => ucfirst(str_replace('_', ' ', $action)) . ' ' . ucfirst($module),
                        'slug'       => $slug,
                        'created_at' => date('Y-m-d H:i:s'),
                    ]);
                }
            }
        }

        // Wire role_permissions based on the matrix in 04-roles-permissions-matrix.md
        foreach ($rolePermissionMap as $roleSlug => $permissionSlugs) {
            $role = $this->db->table('roles')->where('slug', $roleSlug)->get()->getRow();
            if (! $role) {
                continue;
            }
            foreach ($permissionSlugs as $permSlug) {
                $perm = $this->db->table('permissions')->where('slug', $permSlug)->get()->getRow();
                if (! $perm) {
                    continue;
                }
                $exists = $this->db->table('role_permissions')
                    ->where('role_id', $role->id)
                    ->where('permission_id', $perm->id)
                    ->get()->getRow();
                if (! $exists) {
                    $this->db->table('role_permissions')->insert([
                        'role_id'       => $role->id,
                        'permission_id' => $perm->id,
                    ]);
                }
            }
        }
    }

    private function rolePermissionDefaults(): array
    {
        return [
            'super_admin' => [
                'agencies.view_all', 'agencies.verify', 'agencies.suspend',
                'reports.platform_wide', 'settings.global', 'audit.view_platform', 'reviews.moderate',
            ],
            'agency_owner' => [
                'agencies.edit_own', 'recruiters.invite', 'recruiters.remove', 'recruiters.set_permissions',
                'recruiters.view_activity', 'jobs.create', 'jobs.edit', 'jobs.delete', 'jobs.publish',
                'jobs.feature', 'jobs.view', 'candidates.search', 'candidates.contact_reveal',
                'candidates.resume_download', 'candidates.unlock_profile', 'candidates.tag', 'candidates.save',
                'applications.view', 'applications.change_status', 'applications.assign_recruiter',
                'interviews.schedule', 'interviews.reschedule', 'interviews.cancel', 'interviews.feedback',
                'messaging.send', 'billing.manage_plan', 'billing.manage_payment_methods',
                'billing.purchase_credits', 'billing.view_invoices', 'billing.request_refund',
                'reports.agency_scoped', 'settings.agency_scoped', 'audit.view_agency',
            ],
            'recruiter' => [
                // Base defaults — Agency Owner can grant/revoke additional via user_permission_overrides
                'jobs.view', 'candidates.search', 'candidates.contact_reveal', 'candidates.resume_download',
                'candidates.unlock_profile', 'candidates.tag', 'candidates.save', 'applications.view',
                'applications.change_status', 'interviews.schedule', 'interviews.reschedule',
                'interviews.cancel', 'interviews.feedback', 'messaging.send', 'reports.agency_scoped',
            ],
            'candidate' => [
                'applications.apply', 'reviews.submit',
            ],
            'support_staff' => [
                'jobs.view', 'applications.view', 'candidates.search',
            ],
        ];
    }

    private function seedDefaultSettings(): void
    {
        $defaults = [
            ['group' => 'general', 'key' => 'app_name', 'value' => 'Job Portal'],
            ['group' => 'general', 'key' => 'default_currency', 'value' => 'PKR'],
            ['group' => 'general', 'key' => 'default_locale', 'value' => 'en'],
            ['group' => 'seo', 'key' => 'sitemap_enabled', 'value' => '1'],
            ['group' => 'notification', 'key' => 'whatsapp_enabled', 'value' => '0'],
            ['group' => 'profile', 'key' => 'daily_contact_view_limit', 'value' => '10'],
            ['group' => 'profile', 'key' => 'username_change_limit', 'value' => '3'],
            ['group' => 'profile', 'key' => 'username_change_period_days', 'value' => '30'],
            ['group' => 'profile', 'key' => 'require_otp_verification', 'value' => '0'],
        ];

        foreach ($defaults as $setting) {
            $exists = $this->db->table('settings')
                ->where('group', $setting['group'])
                ->where('key', $setting['key'])
                ->get()->getRow();
            if (! $exists) {
                $setting['is_encrypted'] = 0;
                $setting['updated_at']  = date('Y-m-d H:i:s');
                $this->db->table('settings')->insert($setting);
            }
        }
    }
}
