<?php

namespace Core\App\Controllers;

use Core\App\Models\Settings;
use Core\App\Models\OrderModel;
use Core\App\Models\ShippingIntegrationModel;
use Core\App\Integrations\Shipping\EcotrackClient;
use Core\App\Cron\CronRunner;
use Core\App\Cron\Tasks\UpdateShippingStatusTask;
use Core\App\Cron\Tasks\GoogleSheetsExportTask;
use Core\App\Cron\Tasks\SendMeetingRemindersTask;
use Core\System\Csrf;

class CronController
{
    /**
     * ==================================================
     * Main CRON Entry Point
     * URL: /cron/run?token=XXXX
     * Method: GET
     * ==================================================
     */
    public function run()
    {
        header('Content-Type: application/json');

        $settingsModel = new Settings();
        $settings = $settingsModel->getAll();

        /* =========================
           Guards
        ========================= */
        
                /* =========================
           Execution Environment Guard
           (Detect wrong cron usage)
        ========================= */

        // If executed via CLI (php cron.php, or wrong cPanel setup)
        if (php_sapi_name() === 'cli') {
            http_response_code(400);
            echo json_encode([
                'success' => false,
                'error'   => 'INVALID_EXECUTION_MODE',
                'message' => 'This cron endpoint must be executed via HTTP using curl or wget. CLI execution is not supported.'
            ]);
            return;
        }

        // HTTP context sanity check
        if (
            empty($_SERVER['REQUEST_METHOD']) ||
            empty($_SERVER['HTTP_HOST'])
        ) {
            http_response_code(400);
            echo json_encode([
                'success' => false,
                'error'   => 'INVALID_HTTP_CONTEXT',
                'message' => 'Invalid HTTP environment. Make sure this cron is executed using curl or wget.'
            ]);
            return;
        }

        // User-Agent hint (optional but useful for diagnostics)
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';

        if ($userAgent === '') {
            http_response_code(400);
            echo json_encode([
                'success' => false,
                'error'   => 'MISSING_USER_AGENT',
                'message' => 'Cron request has no User-Agent. Use curl or wget in your cron command.'
            ]);
            return;
        }


        // CRON disabled
        if (
            empty($settings['cron_enabled']) ||
            (int)$settings['cron_enabled'] !== 1
        ) {
            http_response_code(403);
            echo json_encode([
                'success' => false,
                'error'   => 'CRON_DISABLED'
            ]);
            return;
        }

        // Token missing
        $token = $_GET['token'] ?? '';
        if ($token === '') {
            http_response_code(401);
            echo json_encode([
                'success' => false,
                'error'   => 'TOKEN_REQUIRED'
            ]);
            return;
        }

        // Invalid token
        if (
            empty($settings['cron_token']) ||
            !hash_equals((string)$settings['cron_token'], (string)$token)
        ) {
            http_response_code(401);
            echo json_encode([
                'success' => false,
                'error'   => 'INVALID_TOKEN'
            ]);
            return;
        }

        /* =========================
           ECOTRACK AUTO SYNC
           (محمي داخليًا من Fatal)
        ========================= */
        try {
            $this->syncEcotrackShipments();
        } catch (\Throwable $e) {
            // لا نوقف الكرون بالكامل
            // نسمح لبقية المهام بالعمل
        }

        /* =========================
           CRON EXECUTION (TASKS)
        ========================= */

        $runner = new CronRunner();

        // Register tasks
        $runner->register(new UpdateShippingStatusTask());
        $runner->register(new GoogleSheetsExportTask());
        $runner->register(new SendMeetingRemindersTask());

        $results = $runner->runAll();

        // ✅ تسجيل آخر تشغيل ناجح للكرون (Timestamp)
        $settingsModel->set('cron_last_run', time());

        echo json_encode([
            'success'     => true,
            'executed_at' => date('Y-m-d H:i:s'),
            'tasks'       => $results
        ]);
        return;
    }

    /**
     * ==================================================
     * Sync Ecotrack Shipments Status
     * ==================================================
     */
    private function syncEcotrackShipments(): void
    {
        $orderModel = new OrderModel();

        // ✅ الدالة موجودة فعليًا بعد التعديل في OrderModel
        $orders = $orderModel->getAllWithEcotrackTracking();

        if (empty($orders)) {
            return;
        }

        $integrationModel = new ShippingIntegrationModel();
        $integration = $integrationModel->getByCode('ecotrack');

        if (!$integration || empty($integration['api_key'])) {
            return;
        }

        $client = new EcotrackClient($integration['api_key']);

        foreach ($orders as $order) {
            if (
                empty($order['extra']['shipping']['tracking'])
            ) {
                continue;
            }

            $tracking = $order['extra']['shipping']['tracking'];

            try {
                $status = $client->track($tracking);
            } catch (\Throwable $e) {
                continue;
            }

            if (empty($status['status'])) {
                continue;
            }

            $extra = $order['extra'];
            $extra['shipping']['status'] = $status['status'];

            // ✅ الدالة أصبحت public في OrderModel
            $orderModel->updateExtra(
                (int)$order['id'],
                $extra
            );
        }
    }

    /**
     * ==================================================
     * Regenerate CRON Token (Admin AJAX)
     * URL: /admin/cron/regenerate
     * Method: POST
     * ==================================================
     */
    public function regenerate()
    {
        header('Content-Type: application/json');

        // ── Admin session guard ──────────────────────────────────────────
        // This endpoint changes a security-critical token; admin login is required.
        if (
            empty($_SESSION['admin_logged_in']) ||
            $_SESSION['admin_logged_in'] !== true ||
            empty($_SESSION['admin_id']) ||
            (int)$_SESSION['admin_id'] <= 0
        ) {
            http_response_code(403);
            echo json_encode(['success' => false, 'error' => 'Unauthorized']);
            exit;
        }
        // ────────────────────────────────────────────────────────────────

        // CSRF protection
        Csrf::check();

        $settingsModel = new Settings();

        try {
            $token = bin2hex(random_bytes(16));
        } catch (\Throwable $e) {
            $token = sha1(uniqid('', true));
        }

        $settingsModel->set('cron_token', $token);

        // Use APP_URL from .env to avoid HTTP_HOST spoofing
        $appUrl = \Core\System\Env::get('APP_URL', '');
        if ($appUrl !== '') {
            $base = rtrim($appUrl, '/');
        } else {
            $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
            $host   = $_SERVER['SERVER_NAME'] ?? 'localhost';
            $base   = rtrim($scheme . '://' . $host, '/');
        }

        $url = $base . '/cron/run?token=' . $token;

        echo json_encode([
            'success' => true,
            'message' => __('settings.cron_generated', 'Cron token regenerated successfully'),
            'url'     => $url,
        ]);
        exit;
    }
}
