<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Helpers\Auth;
use App\Helpers\Url;
use App\Models\Setting;
use App\Models\AuditLog;

class SettingsController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        Auth::requireLogin();
    }

    public function index()
    {
        $settingModel = new Setting();
        // ensure loan_auto_deduction_enabled exists so UI shows the toggle
        $existing = $settingModel->getValue('loan_auto_deduction_enabled', null);
        if ($existing === null) {
            $settingModel->create([
                'group' => 'payment',
                'key' => 'loan_auto_deduction_enabled',
                'value' => 'false',
                'type' => 'boolean',
                'description' => 'Enable/disable automatic loan deduction reminders'
            ]);
        }
        $groups = $settingModel->getGroups();
        $settings = [];

        foreach ($groups as $group) {
            $settings[$group->group] = $settingModel->getByGroup($group->group);
        }

        $dbSize = $this->getDatabaseSize();
        $tables = $this->getTableList();

        $this->view('settings/index', [
            'settingsGroups' => $settings,
            'dbSize' => $dbSize,
            'tables' => $tables,
        ]);
    }

    public function update()
    {
        $settingModel = new Setting();
        $allSettings = $settingModel->all();

        foreach ($allSettings as $setting) {
            if (isset($_POST[$setting->key])) {
                $settingModel->setValue($setting->key, $_POST[$setting->key]);
            }
        }

        if (isset($_FILES['company_logo']) && $_FILES['company_logo']['error'] === UPLOAD_ERR_OK) {
            $this->handleFileUpload('company_logo', 'logo');
        }

        if (isset($_FILES['company_favicon']) && $_FILES['company_favicon']['error'] === UPLOAD_ERR_OK) {
            $this->handleFileUpload('company_favicon', 'logo');
        }

        if (isset($_FILES['home_banner_image']) && $_FILES['home_banner_image']['error'] === UPLOAD_ERR_OK) {
            $this->handleFileUpload('home_banner_image', 'banners');
        }

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'settings.update', 'settings', null, 'Settings updated');

        $_SESSION['success'] = 'Settings saved successfully';
        $this->redirect('/settings');
    }

    public function backup()
    {
        $tables = [];
        $stmt = $this->db->query("SHOW TABLES");
        while ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
            $tables[] = $row[0];
        }

        $output = "-- Database Backup for projects_membershipdb\n";
        $output .= "-- Generated: " . date('Y-m-d H:i:s') . "\n\n";

        foreach ($tables as $table) {
            $stmt = $this->db->query("SHOW CREATE TABLE `$table`");
            $create = $stmt->fetch(\PDO::FETCH_OBJ);
            $output .= "\n\n" . $create->{'Create Table'} . ";\n\n";

            $stmt = $this->db->query("SELECT * FROM `$table`");
            $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

            foreach ($rows as $row) {
                $cols = array_map(function($c) { return "`$c`"; }, array_keys($row));
                $vals = array_map(function($v) {
                    return $v === null ? 'NULL' : $this->db->quote($v);
                }, array_values($row));
                $output .= "INSERT INTO `$table` (" . implode(', ', $cols) . ") VALUES (" . implode(', ', $vals) . ");\n";
            }
        }

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'database.backup', 'settings', null, 'Database backup downloaded');

        header('Content-Type: application/sql');
        header('Content-Disposition: attachment; filename="backup_' . date('Y-m-d_H-i-s') . '.sql"');
        header('Content-Length: ' . strlen($output));
        echo $output;
        exit;
    }

    public function restore()
    {
        if (!isset($_FILES['sql_file']) || $_FILES['sql_file']['error'] !== UPLOAD_ERR_OK) {
            $_SESSION['error'] = 'No SQL file uploaded';
            $this->redirect('/settings');
        }

        $file = $_FILES['sql_file'];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

        if ($ext !== 'sql') {
            $_SESSION['error'] = 'Please upload a .sql file';
            $this->redirect('/settings');
        }

        $sql = file_get_contents($file['tmp_name']);

        try {
            $this->db->exec($sql);
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'database.restore', 'settings', null, 'Database restored from file: ' . $file['name']);
            $_SESSION['success'] = 'Database restored successfully';
        } catch (\Exception $e) {
            $_SESSION['error'] = 'Error restoring database: ' . $e->getMessage();
        }

        $this->redirect('/settings');
    }

    private function getDatabaseSize()
    {
        try {
            $stmt = $this->db->query("SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables WHERE table_schema = 'projects_membershipdb'");
            return $stmt->fetch(\PDO::FETCH_OBJ)->size_mb ?? 0;
        } catch (\Exception $e) {
            return 0;
        }
    }

    private function getTableList()
    {
        $stmt = $this->db->query("SHOW TABLE STATUS FROM `projects_membershipdb`");
        return $stmt->fetchAll(\PDO::FETCH_OBJ);
    }

    public function testEmail()
    {
        $testEmail = $_POST['test_email'] ?? '';
        if (!filter_var($testEmail, FILTER_VALIDATE_EMAIL)) {
            $_SESSION['error'] = 'Please enter a valid email address';
            $this->redirect('/settings');
        }

        $result = \App\Helpers\Mailer::send(
            $testEmail,
            'Test Email - Ghana Anaesthesiologists Society',
            '<h2>SMTP Configuration Test</h2><p>This is a test email from the Ghana Anaesthesiologists Society membership system. If you received this, your SMTP settings are working correctly.</p>'
        );

        if ($result) {
            $_SESSION['success'] = "Test email sent successfully to {$testEmail}.";
        } else {
            $_SESSION['error'] = 'Failed to send test email. Check your SMTP settings and try again.';
        }

        $this->redirect('/settings');
    }

    private function handleFileUpload($fieldName, $subdir)
    {
        if (empty($_FILES[$fieldName]['name'])) {
            return;
        }
        $file = $_FILES[$fieldName];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $allowed = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'ico'];

        if (!in_array($ext, $allowed)) {
            return;
        }

        $uploadDir = $_SERVER['DOCUMENT_ROOT'] . Url::getBaseUrl() . '/uploads/' . $subdir . '/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        $filename = $fieldName . '.' . $ext;
        $dest = $uploadDir . $filename;
        move_uploaded_file($file['tmp_name'], $dest);

        $settingModel = new Setting();
        $settingModel->setValue($fieldName, '/uploads/' . $subdir . '/' . $filename);
    }
}
