<?php
class Role extends Model {
    protected static string $table = 'roles';

    public static function findByTenant(int $tenantId): array {
        $stmt = db()->prepare("SELECT * FROM roles WHERE tenant_id=? ORDER BY is_system DESC, name ASC");
        $stmt->execute([$tenantId]);
        return $stmt->fetchAll();
    }

    public static function findById(int $id, int $tenantId): ?array {
        $stmt = db()->prepare("SELECT * FROM roles WHERE id=? AND tenant_id=?");
        $stmt->execute([$id, $tenantId]);
        return $stmt->fetch() ?: null;
    }

    public static function getPermissions(int $roleId): array {
        $stmt = db()->prepare("
            SELECT p.* FROM permissions p
            JOIN role_permissions rp ON p.id = rp.permission_id
            WHERE rp.role_id = ?
            ORDER BY p.category, p.display_name
        ");
        $stmt->execute([$roleId]);
        return $stmt->fetchAll();
    }

    public static function hasPermission(int $roleId, string $permissionName): bool {
        $stmt = db()->prepare("
            SELECT COUNT(*) FROM role_permissions rp
            JOIN permissions p ON p.id = rp.permission_id
            WHERE rp.role_id = ? AND p.name = ?
        ");
        $stmt->execute([$roleId, $permissionName]);
        return $stmt->fetchColumn() > 0;
    }

    public static function assignPermission(int $roleId, int $permissionId): bool {
        $stmt = db()->prepare("INSERT IGNORE INTO role_permissions (role_id, permission_id) VALUES (?, ?)");
        return $stmt->execute([$roleId, $permissionId]);
    }

    public static function revokePermission(int $roleId, int $permissionId): bool {
        $stmt = db()->prepare("DELETE FROM role_permissions WHERE role_id=? AND permission_id=?");
        return $stmt->execute([$roleId, $permissionId]);
    }

    public static function syncPermissions(int $roleId, array $permissionIds): void {
        // Remove all existing permissions
        $stmt = db()->prepare("DELETE FROM role_permissions WHERE role_id=?");
        $stmt->execute([$roleId]);

        // Assign new permissions
        if (!empty($permissionIds)) {
            $placeholders = implode(',', array_fill(0, count($permissionIds), '?'));
            $stmt = db()->prepare("INSERT INTO role_permissions (role_id, permission_id) SELECT ?, id FROM permissions WHERE id IN ($placeholders)");
            $stmt->execute([$roleId, ...$permissionIds]);
        }
    }

    public static function getUserRole(int $userId): ?array {
        $stmt = db()->prepare("
            SELECT r.* FROM roles r
            JOIN users u ON u.role_id = r.id
            WHERE u.id = ?
        ");
        $stmt->execute([$userId]);
        return $stmt->fetch() ?: null;
    }

    public static function createDefaultRoles(int $tenantId): void {
        $defaultRoles = [
            ['name' => 'Owner', 'description' => 'Full access to all features', 'is_system' => 1],
            ['name' => 'Admin', 'description' => 'Administrative access', 'is_system' => 1],
            ['name' => 'Manager', 'description' => 'Management access', 'is_system' => 1],
            ['name' => 'Teller', 'description' => 'POS and basic operations', 'is_system' => 1],
        ];

        foreach ($defaultRoles as $role) {
            $stmt = db()->prepare("INSERT IGNORE INTO roles (tenant_id, name, description, is_system) VALUES (?, ?, ?, ?)");
            $stmt->execute([$tenantId, $role['name'], $role['description'], $role['is_system']]);
        }
    }

    public static function assignDefaultPermissions(int $tenantId): void {
        // Get all permissions
        $stmt = db()->query("SELECT id, name FROM permissions");
        $permissions = $stmt->fetchAll();

        // Get role IDs
        $owner = db()->prepare("SELECT id FROM roles WHERE tenant_id=? AND name='Owner'");
        $owner->execute([$tenantId]);
        $ownerRole = $owner->fetch();

        $admin = db()->prepare("SELECT id FROM roles WHERE tenant_id=? AND name='Admin'");
        $admin->execute([$tenantId]);
        $adminRole = $admin->fetch();

        $manager = db()->prepare("SELECT id FROM roles WHERE tenant_id=? AND name='Manager'");
        $manager->execute([$tenantId]);
        $managerRole = $manager->fetch();

        $teller = db()->prepare("SELECT id FROM roles WHERE tenant_id=? AND name='Teller'");
        $teller->execute([$tenantId]);
        $tellerRole = $teller->fetch();

        if (!$ownerRole || !$adminRole || !$managerRole || !$tellerRole) return;

        // Owner gets all permissions
        foreach ($permissions as $perm) {
            self::assignPermission($ownerRole['id'], $perm['id']);
        }

        // Admin gets all except billing
        foreach ($permissions as $perm) {
            if ($perm['name'] !== 'billing.view' && $perm['name'] !== 'billing.manage') {
                self::assignPermission($adminRole['id'], $perm['id']);
            }
        }

        // Manager gets inventory, transactions, contacts, and some reports
        $managerPerms = [
            'dashboard.view', 'dashboard.sales_today', 'dashboard.purchase_today',
            'dashboard.total_products', 'dashboard.alerts', 'dashboard.total_month',
            'dashboard.revenue_chart', 'dashboard.recent_sales', 'dashboard.low_stock', 'dashboard.expiring',
            'products.view', 'products.create', 'products.edit',
            'categories.manage', 'units.manage', 'stock.view', 'stock.adjust',
            'sales.view', 'sales.create', 'pos.access', 'purchases.view', 'purchases.create',
            'customers.view', 'customers.create', 'customers.edit',
            'suppliers.view', 'suppliers.create', 'suppliers.edit',
            'supplier_ledger.view', 'customer_ledger.view',
            'reports.view', 'reports.sales', 'reports.inventory', 'reports.expiry', 'reports.stock_valuation'
        ];
        foreach ($permissions as $perm) {
            if (in_array($perm['name'], $managerPerms)) {
                self::assignPermission($managerRole['id'], $perm['id']);
            }
        }

        // Teller gets POS and basic sales
        $tellerPerms = [
            'dashboard.view', 'dashboard.sales_today',
            'sales.view', 'sales.create', 'pos.access',
            'customers.view', 'customers.create', 'products.view'
        ];
        foreach ($permissions as $perm) {
            if (in_array($perm['name'], $tellerPerms)) {
                self::assignPermission($tellerRole['id'], $perm['id']);
            }
        }
    }
}
