<?php
namespace Vanderbilt\REDCap\Classes\Fhir;

use User;
use Project;
use Vanderbilt\REDCap\Classes\Parcel\PostMaster;
use Vanderbilt\REDCap\Classes\Utility\FileCache\FileCache;
use Vanderbilt\REDCap\Classes\Utility\FileCache\NameVisitorInterface;

class FhirAlertManager
{
    private $project_id;
    
    private $project;

    private $postMaster;

    private const ALERT_THROTTLE_TIME = 3 * 3600; // Change as needed

    const ALERT_SENT_FLAG = 'alert-sent';


    public function __construct(int $project_id)
    {
        $this->project_id = $project_id;
        $this->project = new Project($project_id);
        $this->postMaster = new PostMaster();
    }


    /**
     * send a message to the project owner to inform him that no user
     * in the project has a valid token
     *
     * @return string
     */
    public function sendNoTokenMessage() {
        $projectCreatorUsername = $this->getProjectCreatorName();
        if (!$projectCreatorUsername) {
            return;
        }
        // $usernames = $this->getFeedbackUsers();
        // if (empty($usernames)) {
        //     return;
        // }

        $fileCache = $this->getUserFileCache($projectCreatorUsername);
        $messageSentRecently = $fileCache->get(self::ALERT_SENT_FLAG);
        if($messageSentRecently) return;
        
        $message = "Issue: no user in the project has the ability to pull EHR data currently.".PHP_EOL; 
        $message .= "The REDCap CRON job will not be able to automatically pull data from the EHR for project ID {$this->project_id} until at least one person in the project establishes a connection to the EHR (via Standalone Launch or EHR launch).";
        $parcel_id = $this->sendAlert($projectCreatorUsername, $message);
        $fileCache->set(self::ALERT_SENT_FLAG, time(), self::ALERT_THROTTLE_TIME);
        return $parcel_id;
    }

    public function sendAlert(string $to, string $message): string
    {
        // Title for the alert
        $title = sprintf('FHIR Alert - PID %d', $this->project_id);
        // Prepare alert content
        $html = '[This message was automatically generated by REDCap]' . PHP_EOL;
        $html .= $message;

        // Send alert
        return $this->postMaster->sendParcel(
            $to, // to
            'REDCap - FHIR Alert Manager', // from
            $title, // subject
            $html // body
        );
    }

    private function getUserFileCache($username) {
        $prefix = "$username - $this->project_id - ";
        // use a visitor class to alter the name of the cache file
        $nameVisitor = new class($prefix) implements NameVisitorInterface {
            private $prefix;

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

            function visit($key, $hashedFilename, $extension) {
                $filename = $this->prefix.$hashedFilename;
                $extension = 'fa'; // FHIR Alert
                return [$filename, $extension];
            }
        };
        $fileCache = new FileCache(__CLASS__, APP_PATH_TEMP, $nameVisitor);
        return $fileCache;
    }

    private function getProjectCreatorName() {
        // Retrieve project creator
        $projectCreatorId = $this->project->project['created_by'] ?? null;
        if (!$projectCreatorId) return;
        $userInfo = User::getUserInfoByUiid($projectCreatorId);
        $username = $userInfo['username'] ?? null;
        return $username;
    }

    /**
     * return a list of users eligible for feedback
     * users are selected based on the user rights of a project and
     * ordered based on the FHIR interaction they had
     *
     * @return array
     */
    private function getFeedbackUsers() {
        $queryString = "SELECT `ui`.`ui_id`,`ui`.`username`, `logs`.`created_at`
            FROM `redcap_user_information` AS ui
            LEFT JOIN `redcap_user_rights` AS `ur` ON `ui`.`username`=`ur`.`username`
            LEFT JOIN (
                SELECT `user_id`, MAX(`created_at`) AS `created_at`
                FROM `redcap_ehr_fhir_logs`
                WHERE `project_id` = ? AND `user_id` IS NOT NULL
                GROUP BY `user_id
            ) AS logs ON `logs`.`user_id`=`ui`.`ui_id`
            WHERE `project_id`= ?
            ORDER BY `logs`.`created_at` DESC";
        $params = [$this->project_id, $this->project_id];
        $result = db_query($queryString, $params);
        if(!$result) return [];
        $users = [];
        while($row=db_fetch_assoc($result)) {
            $ui_id = $row['ui_id'] ?? '';
            $username = $row['username'] ?? '';
            $users[$ui_id] = $username;
        }
        return $users;
    }
}
