<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class GrantSubjectCurriculumPermission extends Migration
{
    private string $permissionName = 'update_curriculum';

    public function up(): void
    {
        if (
            ! $this->db->tableExists('roles')
            || ! $this->db->tableExists('permissions')
            || ! $this->db->tableExists('role_permissions')
        ) {
            return;
        }

        $now = date('Y-m-d H:i:s');
        $permission = $this->db->table('permissions')
            ->where('name', $this->permissionName)
            ->get()
            ->getRowArray();

        if ($permission === null) {
            $insert = [
                'name' => $this->permissionName,
                'created_at' => $now,
                'updated_at' => $now,
            ];

            if ($this->db->fieldExists('description', 'permissions')) {
                $insert['description'] = 'Manage subject curriculum entries';
            }

            $this->db->table('permissions')->insert($insert);
            $permissionId = (int) $this->db->insertID();
        } else {
            $permissionId = (int) $permission['id'];
        }

        if ($permissionId <= 0) {
            return;
        }

        $roleRows = $this->db->table('roles')
            ->select('id, name')
            ->whereIn('name', [
                'administrator',
                'admin',
                'principal',
                'vice principal',
                'vice_principal',
                'administrative staff',
            ])
            ->get()
            ->getResultArray();

        foreach ($roleRows as $role) {
            $roleId = (int) ($role['id'] ?? 0);
            if ($roleId <= 0) {
                continue;
            }

            $existing = $this->db->table('role_permissions')
                ->where('role_id', $roleId)
                ->where('permission_id', $permissionId)
                ->get()
                ->getRowArray();

            $permissionData = [
                'can_create' => 1,
                'can_read' => 1,
                'can_update' => 1,
                'can_delete' => 1,
                'updated_at' => $now,
            ];

            if ($this->db->fieldExists('can_manage', 'role_permissions')) {
                $permissionData['can_manage'] = 1;
            }

            if ($existing === null) {
                $permissionData['role_id'] = $roleId;
                $permissionData['permission_id'] = $permissionId;
                $permissionData['created_at'] = $now;

                $this->db->table('role_permissions')->insert($permissionData);
                continue;
            }

            $this->db->table('role_permissions')
                ->where('id', (int) $existing['id'])
                ->update($permissionData);
        }
    }

    public function down(): void
    {
        if (
            ! $this->db->tableExists('roles')
            || ! $this->db->tableExists('permissions')
            || ! $this->db->tableExists('role_permissions')
        ) {
            return;
        }

        $permission = $this->db->table('permissions')
            ->select('id')
            ->where('name', $this->permissionName)
            ->get()
            ->getRowArray();

        if ($permission === null) {
            return;
        }

        $roleRows = $this->db->table('roles')
            ->select('id')
            ->whereIn('name', [
                'administrator',
                'admin',
                'principal',
                'vice principal',
                'vice_principal',
                'administrative staff',
            ])
            ->get()
            ->getResultArray();

        $roleIds = array_map(static fn(array $role): int => (int) ($role['id'] ?? 0), $roleRows);
        $roleIds = array_values(array_filter($roleIds, static fn(int $roleId): bool => $roleId > 0));

        if ($roleIds === []) {
            return;
        }

        $this->db->table('role_permissions')
            ->where('permission_id', (int) $permission['id'])
            ->whereIn('role_id', $roleIds)
            ->delete();
    }
}
