<?php
class RoleController extends Controller
{
    public function index(Request $request): void
    {
        $this->view('roles/index', [
            'title' => lang('admin.roles'),
            'breadcrumbs' => [
                ['label' => lang('admin.administration'), 'url' => '/admin/roles'],
                ['label' => lang('admin.roles')]
            ],
        ]);
    }

    public function datatable(Request $request): void
    {
        $db = $this->db();
        $draw = (int)$request->post('draw', 1);
        $start = (int)$request->post('start', 0);
        $length = (int)$request->post('length', 25);
        $search = trim($request->post('search')['value'] ?? '');

        $where = "1=1";
        $params = [];
        if ($search !== '') {
            $where .= " AND (r.role_code LIKE ? OR r.role_name_en LIKE ? OR r.role_name_ar LIKE ?)";
            $s = "%{$search}%";
            $params = [$s, $s, $s];
        }

        $total = (int)$db->fetchColumn("SELECT COUNT(*) FROM auth_roles r");
        $filtered = (int)$db->fetchColumn("SELECT COUNT(*) FROM auth_roles r WHERE {$where}", $params);

        $rows = $db->fetchAll(
            "SELECT r.*, (SELECT COUNT(*) FROM auth_user_roles ur WHERE ur.role_id = r.id AND ur.is_active = 1) as user_count,
                    (SELECT COUNT(*) FROM auth_role_permissions rp WHERE rp.role_id = r.id) as perm_count
             FROM auth_roles r WHERE {$where} ORDER BY r.sort_order ASC, r.id ASC LIMIT {$length} OFFSET {$start}",
            $params
        );

        $data = [];
        foreach ($rows as $row) {
            $actions = '<div class="btn-group btn-group-sm">';
            $actions .= '<a href="/admin/roles/' . $row['id'] . '/edit" class="btn btn-outline-primary"><i class="fas fa-edit"></i></a>';
            if (!$row['is_system']) {
                $actions .= '<button class="btn btn-outline-danger btn-delete-role" data-id="' . $row['id'] . '"><i class="fas fa-trash"></i></button>';
            }
            $actions .= '</div>';

            $data[] = [
                'id'         => $row['id'],
                'code'       => e($row['role_code']),
                'name'       => e($row['role_name_en']),
                'name_ar'    => e($row['role_name_ar']),
                'users'      => $row['user_count'],
                'permissions' => $row['perm_count'],
                'system'     => $row['is_system'] ? '<span class="badge bg-info">System</span>' : '',
                'active'     => $row['is_active'] ? '<span class="badge bg-success">Active</span>' : '<span class="badge bg-secondary">Inactive</span>',
                'actions'    => $actions,
            ];
        }

        $this->json(['draw' => $draw, 'recordsTotal' => $total, 'recordsFiltered' => $filtered, 'data' => $data]);
    }

    public function create(Request $request): void
    {
        $db = $this->db();
        $permissions = $db->fetchAll("SELECT * FROM auth_permissions WHERE is_active = 1 ORDER BY module, category, permission_code");
        $modules = [];
        foreach ($permissions as $p) {
            $modules[$p['module']][] = $p;
        }

        $this->view('roles/form', [
            'title' => lang('admin.create_role'),
            'breadcrumbs' => [
                ['label' => lang('admin.administration'), 'url' => '/admin/roles'],
                ['label' => lang('admin.roles'), 'url' => '/admin/roles'],
                ['label' => lang('admin.create_role')]
            ],
            'role' => null,
            'modules' => $modules,
            'rolePermissions' => [],
        ]);
    }

    public function store(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'Invalid CSRF'], 403); return; }

        $validator = new Validator($request->all(), [
            'role_code'    => 'required|string|max:50',
            'role_name_en' => 'required|string|max:200',
            'role_name_ar' => 'required|string|max:200',
        ]);
        if ($validator->fails()) { $this->json(['success' => false, 'errors' => $validator->errors()], 422); return; }

        $db = $this->db();
        $exists = $db->fetchColumn("SELECT COUNT(*) FROM auth_roles WHERE role_code = ?", [$request->post('role_code')]);
        if ($exists) { $this->json(['success' => false, 'errors' => ['role_code' => ['Role code already exists']]], 422); return; }

        $db->beginTransaction();
        try {
            $roleId = $db->insert('auth_roles', [
                'role_code'      => $request->post('role_code'),
                'role_name_en'   => $request->post('role_name_en'),
                'role_name_ar'   => $request->post('role_name_ar'),
                'description_en' => $request->post('description_en'),
                'description_ar' => $request->post('description_ar'),
                'is_system'      => 0,
                'is_active'      => $request->post('is_active', 1) ? 1 : 0,
                'created_by'     => Auth::id(),
            ]);

            $permIds = $request->post('permissions', []);
            if (is_array($permIds)) {
                foreach ($permIds as $pid) {
                    $db->insert('auth_role_permissions', [
                        'role_id'       => $roleId,
                        'permission_id' => (int)$pid,
                        'granted_by'    => Auth::id(),
                    ]);
                }
            }

            $this->audit('create', 'auth_roles', $roleId, 'Created role: ' . $request->post('role_code'));
            $db->commit();
            $this->json(['success' => true, 'message' => 'Role created', 'redirect' => '/admin/roles']);
        } catch (\Exception $e) {
            $db->rollBack();
            Logger::error('Role creation failed: ' . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Failed to create role'], 500);
        }
    }

    public function edit(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        $db = $this->db();
        $role = $db->fetchOne("SELECT * FROM auth_roles WHERE id = ?", [$id]);
        if (!$role) { $this->abort(404); return; }

        $permissions = $db->fetchAll("SELECT * FROM auth_permissions WHERE is_active = 1 ORDER BY module, category, permission_code");
        $modules = [];
        foreach ($permissions as $p) { $modules[$p['module']][] = $p; }

        $rolePerms = $db->fetchAll("SELECT permission_id FROM auth_role_permissions WHERE role_id = ?", [$id]);
        $rolePermIds = array_column($rolePerms, 'permission_id');

        $this->view('roles/form', [
            'title' => lang('admin.edit_role') . ': ' . $role['role_name_en'],
            'breadcrumbs' => [
                ['label' => lang('admin.administration'), 'url' => '/admin/roles'],
                ['label' => lang('admin.roles'), 'url' => '/admin/roles'],
                ['label' => lang('admin.edit_role')]
            ],
            'role' => $role,
            'modules' => $modules,
            'rolePermissions' => $rolePermIds,
        ]);
    }

    public function update(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'Invalid CSRF'], 403); return; }

        $validator = new Validator($request->all(), [
            'role_name_en' => 'required|string|max:200',
            'role_name_ar' => 'required|string|max:200',
        ]);
        if ($validator->fails()) { $this->json(['success' => false, 'errors' => $validator->errors()], 422); return; }

        $db = $this->db();
        $db->beginTransaction();
        try {
            $db->update('auth_roles', [
                'role_name_en'   => $request->post('role_name_en'),
                'role_name_ar'   => $request->post('role_name_ar'),
                'description_en' => $request->post('description_en'),
                'description_ar' => $request->post('description_ar'),
                'is_active'      => $request->post('is_active', 1) ? 1 : 0,
            ], 'id = ?', [$id]);

            $db->delete('auth_role_permissions', 'role_id = ?', [$id]);
            $permIds = $request->post('permissions', []);
            if (is_array($permIds)) {
                foreach ($permIds as $pid) {
                    $db->insert('auth_role_permissions', [
                        'role_id'       => $id,
                        'permission_id' => (int)$pid,
                        'granted_by'    => Auth::id(),
                    ]);
                }
            }

            $this->audit('update', 'auth_roles', $id, 'Updated role permissions');
            $db->commit();
            $this->json(['success' => true, 'message' => 'Role updated', 'redirect' => '/admin/roles']);
        } catch (\Exception $e) {
            $db->rollBack();
            $this->json(['success' => false, 'message' => 'Failed to update role'], 500);
        }
    }

    public function destroy(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'Invalid CSRF'], 403); return; }
        $db = $this->db();
        $role = $db->fetchOne("SELECT * FROM auth_roles WHERE id = ?", [$id]);
        if (!$role || $role['is_system']) { $this->json(['success' => false, 'message' => 'Cannot delete system role'], 400); return; }
        $userCount = $db->fetchColumn("SELECT COUNT(*) FROM auth_user_roles WHERE role_id = ? AND is_active = 1", [$id]);
        if ($userCount > 0) { $this->json(['success' => false, 'message' => 'Role has assigned users. Remove them first.'], 400); return; }

        $db->delete('auth_role_permissions', 'role_id = ?', [$id]);
        $db->delete('auth_roles', 'id = ?', [$id]);
        $this->audit('delete', 'auth_roles', $id, 'Deleted role: ' . $role['role_code']);
        $this->json(['success' => true, 'message' => 'Role deleted']);
    }
}