<?php
require_once 'config/database.php';
require_once 'controllers/CommunicationSenderController.php';

class SettingsController {
    private $conn;
    private $sender;

    public function __construct() {
        $database = new Database();
        $this->conn = $database->getConnection();
        $this->sender = new CommunicationSenderController();
    }

    // PROFILE
    public function updateProfile($data, $userId) {
        $required = ['first_name', 'last_name', 'email', 'phone'];
        foreach ($required as $field) {
            if (!isset($data[$field])) return $this->error("Missing $field");
        }

        $query = "UPDATE users SET 
                    first_name = :first_name, 
                    last_name = :last_name, 
                    email = :email, 
                    phone = :phone, 
                    updated_at = NOW() 
                  WHERE id = :id";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([
            ':first_name' => $data['first_name'],
            ':last_name' => $data['last_name'],
            ':email' => $data['email'],
            ':phone' => $data['phone'],
            ':id' => $userId
        ]);

        return $this->success('Profile updated successfully');
    }

    // NOTIFICATIONS (Now in `users` table)
    public function updateNotifications($data, $userId) {
        $fields = [
            'email_notifications' => $data['email_notifications'] ?? 1,
            'sms_notifications' => $data['sms_notifications'] ?? 0,
            'push_notifications' => $data['push_notifications'] ?? 1,
            'escalation_alerts' => $data['escalation_alerts'] ?? 1,
            'performance_reports' => $data['performance_reports'] ?? 1
        ];

        $setClause = '';
        $params = [':id' => $userId];
        foreach ($fields as $col => $val) {
            $setClause .= "$col = :$col, ";
            $params[":$col"] = $val ? 1 : 0;
        }
        $setClause = rtrim($setClause, ', ');

        $query = "UPDATE users SET $setClause WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->execute($params);

        return $this->success('Notification preferences saved');
    }

    public function getNotifications($userId) {
        $query = "SELECT 
                    email_notifications,
                    sms_notifications,
                    push_notifications,
                    escalation_alerts,
                    performance_reports
                  FROM users WHERE id = :id";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([':id' => $userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$row) return $this->error('User not found');

        // Convert TINYINT to boolean
        foreach ($row as $key => $value) {
            $row[$key] = (bool)$value;
        }

        return $this->success('', $row);
    }

    // SYSTEM SETTINGS
    public function getSystemSettings() {
        $query = "SELECT setting_key, setting_value, setting_type FROM system_settings";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $settings = [];
        foreach ($rows as $row) {
            $value = $row['setting_value'];
            if ($row['setting_type'] === 'bool') $value = (bool)$value;
            if ($row['setting_type'] === 'int') $value = (int)$value;
            if ($row['setting_type'] === 'json') $value = json_decode($value, true);
            $settings[$row['setting_key']] = $value;
        }

        return $this->success('Settings loaded', $settings);
    }

    public function updateSystemSetting($data) {
        if (!isset($data['key'], $data['value'])) {
            return $this->error('Missing key or value');
        }

        $type = $this->detectType($data['value']);
        $value = $type === 'json' ? json_encode($data['value']) : $data['value'];

        $query = "INSERT INTO system_settings (setting_key, setting_value, setting_type) 
                  VALUES (:key, :value, :type)
                  ON DUPLICATE KEY UPDATE 
                  setting_value = :value, setting_type = :type";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([
            ':key' => $data['key'],
            ':value' => $value,
            ':type' => $type
        ]);

        return $this->success('System setting updated');
    }

    // EMAIL TEMPLATES
    public function getEmailTemplates() {
        $query = "SELECT * FROM email_templates WHERE is_active = 1 ORDER BY name";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        return $this->success('Templates loaded', $stmt->fetchAll(PDO::FETCH_ASSOC));
    }

    public function getEmailTemplateByKey($key) {
        $query = "SELECT * FROM email_templates WHERE template_key = :key AND is_active = 1";
        $stmt = $this->conn->prepare($query);
        $stmt->execute([':key' => $key]);
        $template = $stmt->fetch(PDO::FETCH_ASSOC);
        return $template ? $this->success('Template found', $template) : $this->error('Template not found');
    }

    public function updateEmailTemplate($data) {
        if (!isset($data['template_key'], $data['subject'], $data['body'])) {
            return $this->error('Missing required fields: template_key, subject, body');
        }

        $variables = $this->extractVariables($data['body'] . ' ' . $data['subject']);

        $query = "INSERT INTO email_templates 
                  (template_key, name, subject, body, variables) 
                  VALUES (:key, :name, :subject, :body, :variables)
                  ON DUPLICATE KEY UPDATE 
                  name = :name, subject = :subject, body = :body, variables = :variables";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([
            ':key' => $data['template_key'],
            ':name' => $data['name'] ?? ucwords(str_replace('_', ' ', $data['template_key'])),
            ':subject' => $data['subject'],
            ':body' => $data['body'],
            ':variables' => json_encode($variables)
        ]);

        return $this->success('Email template saved');
    }

    // BACKUP
    public function createBackup() {
        $backupName = 'backup_' . date('Y-m-d_H-i-s');
        $filePath = "../backups/{$backupName}.sql"; // Adjust path

        $command = sprintf(
            'mysqldump -u %s -p%s %s > %s',
            escapeshellarg(USERNAME),
            escapeshellarg(PASSWORD),
            escapeshellarg(DB_NAME),
            escapeshellarg($filePath)
        );

        exec($command . ' 2>&1', $output, $returnCode);

        $status = $returnCode === 0 ? 'completed' : 'failed';
        $size = $returnCode === 0 ? round(filesize($filePath) / (1024 * 1024), 2) : 0;

        $query = "INSERT INTO system_backups 
                  (backup_name, file_path, file_size_mb, status, backup_type) 
                  VALUES (:name, :path, :size, :status, 'manual')";

        $stmt = $this->conn->prepare($query);
        $stmt->execute([
            ':name' => $backupName,
            ':path' => $filePath,
            ':size' => $size,
            ':status' => $status
        ]);

        return $returnCode === 0
            ? $this->success('Backup created successfully')
            : $this->error('Backup failed: ' . implode('; ', $output));
    }

    public function getBackups() {
        $query = "SELECT id, backup_name, file_size_mb, status, created_at 
                  FROM system_backups 
                  ORDER BY created_at DESC LIMIT 10";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        return $this->success('Backups loaded', $stmt->fetchAll(PDO::FETCH_ASSOC));
    }

    public function systemHealthCheck() {
        $checks = [
            'database' => $this->conn->query("SELECT 1")->fetch() ? 'OK' : 'Failed',
            'disk_space_gb' => round(disk_free_space('/') / (1024**3), 2),
            'php_version' => PHP_VERSION,
            'backup_dir_writable' => is_writable('../backups') ? 'Yes' : 'No'
        ];

        return $this->success('Health check complete', $checks);
    }

    public function changePassword($data, $userId) {
        if (!isset($data['current_password'], $data['new_password'])) {
            return $this->error('Missing current_password or new_password');
        }

        // Fetch current password hash
        $query = "SELECT password_hash FROM users WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->execute([':id' => $userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$row || !password_verify($data['current_password'], $row['password_hash'])) {
            return $this->error('Current password is incorrect');
        }

        // password match check
        if ($data['current_password'] === $data['new_password']) {
            return $this->error('New password cannot be the same as the current password');
        }

        // new password unmatch check
        if (isset($data['confirm_password']) && $data['new_password'] !== $data['confirm_password']) {
            return $this->error('New password and confirm password do not match');
        }

        // Update to new password
        $newHash = password_hash($data['new_password'], PASSWORD_BCRYPT);
        $updateQuery = "UPDATE users SET password_hash = :password, updated_at = NOW() WHERE id = :id";
        $updateStmt = $this->conn->prepare($updateQuery);
        $updateStmt->execute([
            ':password' => $newHash,
            ':id' => $userId
        ]);

        return $this->success('Password changed successfully');
    }

    // Helpers
    private function detectType($value) {
        if (is_bool($value)) return 'bool';
        if (is_numeric($value) && strpos($value, '.') === false) return 'int';
        if (is_array($value)) return 'json';
        return 'string';
    }

    private function extractVariables($text) {
        preg_match_all('/\{([^}]+)\}/', $text, $matches);
        return array_unique($matches[1]);
    }

    private function success($message, $data = []) {
        return json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
    }

    private function error($message) {
        return json_encode(['status' => 'error', 'message' => $message]);
    }
}