<?php
// classes/Permission.php
class Permission {
    private $pdo;
    private $columnExistenceCache = [];

    public function __construct($pdo) {
        $this->pdo = $pdo;
    }

    /**
     * Checks if a user has a specific permission for a data source.
     * @param int $personId The person's ID (fkisp_id).
     * @param int $dataSourceId The data source ID (pkdspsds_id).
     * @param string $permissionType The type of permission (e.g., 'Read', 'Download').
     * @return bool True if the permission is granted, false otherwise.
     */
    public function hasPermission($personId, $dataSourceId, $permissionType) {
        $sql = "SELECT COUNT(*) FROM dsps_tbl_datasource_permission 
                WHERE fkisp_id_of = ? AND fkdspsds_id = ? 
                AND dspsdsp_permission = ? AND dspsdsp_status = 'Approved'";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$personId, $dataSourceId, $permissionType]);
        return $stmt->fetchColumn() > 0;
    }

    /**
     * Gets a pending request for a user and data source, if one exists.
     * @param int $personId The person's ID (fkisp_id).
     * @param int $dataSourceId The data source ID (pkdspsds_id).
     * @param string $permissionType The type of permission.
     * @return array|false The request data as an array, or false if not found.
     */
    public function getPendingRequest($personId, $dataSourceId, $permissionType) {
        $sql = "SELECT * FROM dsps_tbl_datasource_permission 
                WHERE fkisp_id_of = ? AND fkdspsds_id = ? 
                AND dspsdsp_permission = ? AND dspsdsp_status = 'Pending'";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$personId, $dataSourceId, $permissionType]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    /**
     * Adds a new permission request to the database.
     * @param int $personId The person's ID (fkisp_id).
     * @param int $dataSourceId The data source ID (pkdspsds_id).
     * @param string $permissionType The type of permission requested.
     * @param string $status The initial status of the request (e.g., 'Pending').
     * @param string $notes The user's justification for the request.
     * @return bool True on success, false on failure.
     */
    public function addPermissionRequest($personId, $dataSourceId, $permissionType, $status, $notes, ?string $proofPath = null) {
        $hasProofColumn = $this->ensurePermissionProofColumn();

        if ($hasProofColumn) {
            $sql = "INSERT INTO dsps_tbl_datasource_permission (fkisp_id_of, fkdspsds_id, dspsdsp_permission, dspsdsp_notes, dspsdsp_proof_path, dspsdsp_status, dspsdsp_datetime)
                    VALUES (?, ?, ?, ?, ?, ?, NOW())";
            $params = [$personId, $dataSourceId, $permissionType, $notes, $proofPath, $status];
        } else {
            $sql = "INSERT INTO dsps_tbl_datasource_permission (fkisp_id_of, fkdspsds_id, dspsdsp_permission, dspsdsp_notes, dspsdsp_status, dspsdsp_datetime)
                    VALUES (?, ?, ?, ?, ?, NOW())";
            $params = [$personId, $dataSourceId, $permissionType, $notes, $status];
        }
        
        $stmt = $this->pdo->prepare($sql);
        return $stmt->execute($params);
    }

    /**
     * Gets all permission requests for a specific user.
     * This method is needed for the 'my_permissions.php' script.
     * @param int $personId The person's ID (fkisp_id).
     * @return array An array of all permission requests for the given person.
     */
    public function getPermissionsByPersonId($personId) {
        $hasProofColumn = $this->ensurePermissionProofColumn();
        $proofSelect = $hasProofColumn
            ? 'pr.dspsdsp_proof_path AS dspspr_proof_path'
            : 'NULL AS dspspr_proof_path';

        $sql = "SELECT 
                    ds.dspsds_title_en AS ds_title,
                    pr.dspsdsp_permission AS dspspr_permission_type,
                    pr.dspsdsp_reg_datetime AS dspspr_request_date,
                    pr.dspsdsp_status AS dspspr_status,
                    pr.dspsdsp_notes AS dspspr_notes,
                    $proofSelect
                FROM dsps_tbl_datasource_permission pr
                JOIN dsps_tbl_datasource ds ON pr.fkdspsds_id = ds.pkdspsds_id
                WHERE pr.fkisp_id_of = ?";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$personId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    private function tableColumnExists(string $table, string $column): bool {
        $cacheKey = $table . '.' . $column;
        if (array_key_exists($cacheKey, $this->columnExistenceCache)) {
            return $this->columnExistenceCache[$cacheKey];
        }

        if (!preg_match('/^[a-zA-Z0-9_]+$/', $table)) {
            return false;
        }

        $sql = sprintf('SHOW COLUMNS FROM `%s` LIKE :column', $table);
        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindParam(':column', $column, PDO::PARAM_STR);
            $stmt->execute();
            $exists = (bool) $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            error_log('Error checking column existence: ' . $e->getMessage());
            // Assume the column exists if we cannot verify (safer than silently skipping writes)
            $exists = true;
        }

        $this->columnExistenceCache[$cacheKey] = $exists;
        return $exists;
    }

    private function ensurePermissionProofColumn(): bool {
        $table = 'dsps_tbl_datasource_permission';
        $column = 'dspsdsp_proof_path';
        $cacheKey = $table . '.' . $column;

        if ($this->tableColumnExists($table, $column)) {
            return true;
        }

        $alterSql = "ALTER TABLE `{$table}` ADD COLUMN `{$column}` VARCHAR(255) DEFAULT NULL AFTER dspsdsp_notes";
        try {
            $this->pdo->exec($alterSql);
            $this->columnExistenceCache[$cacheKey] = true;
            return true;
        } catch (PDOException $e) {
            error_log('Failed to add proof column: ' . $e->getMessage());
            return false;
        }
    }
}
