<?php

declare(strict_types=1);

class ReminderJob extends Job
{
    private BehaviorTracker $tracker;

    private const CTA_DEFINITIONS = [
        'start' => [
            'soft' => ['label' => '✨ ادامه ثبت‌نام', 'callback' => 'ev_join:%d:%d'],
            'normal' => ['label' => '⚡ ادامه تکمیل', 'callback' => 'ev_join:%d:%d'],
            'urgent' => ['label' => '🚀 تکمیل فوری', 'callback' => 'ev_join:%d:%d'],
        ],
        'ign' => [
            'soft' => ['label' => '📝 وارد کردن IGN', 'callback' => 'ev_join:%d:%d'],
            'normal' => ['label' => '📝 تکمیل IGN', 'callback' => 'ev_join:%d:%d'],
            'urgent' => ['label' => '🚨 تکمیل IGN', 'callback' => 'ev_join:%d:%d'],
        ],
        'game_id' => [
            'soft' => ['label' => '🆔 ثبت Game ID', 'callback' => 'ev_join:%d:%d'],
            'normal' => ['label' => '🆔 وارد کردن Game ID', 'callback' => 'ev_join:%d:%d'],
            'urgent' => ['label' => '🚨 ثبت Game ID', 'callback' => 'ev_join:%d:%d'],
        ],
        'referral' => [
            'soft' => ['label' => '👥 دعوت دوستان', 'callback' => 'ev_join:%d:%d'],
            'normal' => ['label' => '👥 ادامه دعوت', 'callback' => 'ev_join:%d:%d'],
            'urgent' => ['label' => '🚀 دعوت سریع', 'callback' => 'ev_join:%d:%d'],
        ],
        'force_join' => [
            'soft' => ['label' => '📢 ادامه عضویت', 'callback' => 'check_join:%d'],
            'normal' => ['label' => '📢 تکمیل عضویت', 'callback' => 'check_join:%d'],
            'urgent' => ['label' => '🚨 عضویت فوری', 'callback' => 'check_join:%d'],
        ],
        'payment' => [
            'soft' => ['label' => '💳 ارسال رسید', 'callback' => 'pay_notify:%d:card'],
            'normal' => ['label' => '💳 تکمیل پرداخت', 'callback' => 'pay_notify:%d:card'],
            'urgent' => ['label' => '🚀 ارسال رسید', 'callback' => 'pay_notify:%d:card'],
        ],
    ];

    private SmartReminderEngine $engine;
    private EventFunnelAI $ai;
    private ReminderToneResolver $toneResolver;

    public function __construct(PDO $pdo)
    {
        parent::__construct($pdo);

        $this->engine = new SmartReminderEngine();
        $this->ai = new EventFunnelAI();
        $this->toneResolver = new ReminderToneResolver();
        $this->tracker = new BehaviorTracker($pdo);
    }

    public function getName(): string
    {
        return 'ReminderJob';
    }


    public function handle(): void
    {
        $this->log('ReminderJob Started');

        $st = $this->pdo->prepare("
            SELECT rp.*, e.name AS event_name, e.deadline
            FROM event_registration_progress rp
            JOIN events e ON e.id = rp.event_id
            WHERE rp.current_step != 'completed'
            LIMIT 200
        ");

        $st->execute();
        $rows = $st->fetchAll(PDO::FETCH_ASSOC);

        $this->log('Rows loaded', [
            'count' => count($rows)
        ]);

        foreach ($rows as $row) {

            $this->log('Processing user', [
                'user' => $row['user_id'],
                'event' => $row['event_id'],
                'step' => $row['current_step'],
                'reminders' => $row['reminder_count']
            ]);

            if (
                !empty($row['deadline'])
                && strtotime($row['deadline']) <= time()
            ) {
                $this->log('Skipped: event expired', [
                    'user' => $row['user_id'],
                    'event' => $row['event_id']
                ]);

                continue;
            }

            $decision = $this->engine->decide($row);

            $this->log('Decision', $decision->toArray());

            if (!$decision->send) {
                $this->log('Blocked by engine', [
                    'user' => $row['user_id'],
                    'decision' => $decision->toArray()
                ]);

                continue;
            }

            $tone = $this->toneResolver->resolve(
                (int)$row['reminder_count']
            );

            $this->log('Tone resolved', [
                'user' => $row['user_id'],
                'reminder_count' => $row['reminder_count'],
                'tone' => $tone
            ]);

            if ($tone === null) {
                $this->log('Skipped: reminder limit reached', [
                    'user' => $row['user_id'],
                    'reminder_count' => $row['reminder_count']
                ]);

                continue;
            }

            $step = $this->normalizeStep(
                (string)$row['current_step']
            );

            $message = $this->buildReminderMessage(
                $row,
                $step,
                $tone
            );

            $this->log('Message built', [
                'user' => $row['user_id'],
                'step' => $step,
                'tone' => $tone,
                'message_created' => $message !== null
            ]);

            if ($message === null) {
                continue;
            }

            $ctaKeyboard = $this->buildCtaKeyboard(
                $row,
                $step,
                $tone
            );

            $this->log('Before telegram send', [
                'user' => $row['user_id'],
                'has_keyboard' => $ctaKeyboard !== null
            ]);

            $sent = $this->sendTelegram(
                (int)$row['user_id'],
                $message,
                $ctaKeyboard
            );

            if (!$sent) {
                $this->log('Telegram send failed', [
                    'user' => $row['user_id']
                ]);

                continue;
            }

            $this->tracker->reminderSent(
                (int)$row['event_id'],
                (int)$row['user_id'],
                $decision,
                $row
            );

            $this->log('Reminder recorded', [
                'user' => $row['user_id'],
                'event' => $row['event_id'],
                'tone' => $tone
            ]);
        }
    }

/*
    private function markAsSent(int $id): void
    {
        $st = $this->pdo->prepare("
            UPDATE event_registration_progress
            SET 
                reminder_count = reminder_count + 1,
                last_reminder_at = NOW()
            WHERE id = ?
        ");

        $st->execute([$id]);
    }
*/
    private function normalizeStep(string $step): string
    {
        return $step === 'private_channel' || $step === 'force_join' ? 'force_join' : $step;
    }

    private function countReferral(int $uid, int $eid): int
    {
        $st = $this->pdo->prepare("
            SELECT COUNT(*)
            FROM referral_starts
            WHERE referrer_id = ?
            AND event_id = ?
            AND status = 'valid'
        ");

        $st->execute([$uid, $eid]);

        return (int)$st->fetchColumn();
    }

    /**
     * پیام هوشمند بر اساس AI
     */
    private function buildReminderMessage(array $row, string $step, string $level): ?string
    {

    $event = $row['event_name'];

    $uid = (int)$row['user_id'];
    $eid = (int)$row['event_id'];

    $validReferrals = $this->countReferral($uid, $eid);

    $requiredReferrals = (int)($row['required_referrals'] ?? 1);

    $remainingReferrals = max(
        0,
        $requiredReferrals - $validReferrals
    );

    $remainingReferralsText = numberToPersianWords($remainingReferrals);

    return match ($level) {

        'soft' => match ($step) {
            'start' =>
                "🎮 ثبت‌نام <b>{$event}</b> رو شروع کردی؛ هر وقت آماده‌ای، ادامه‌ش بده.",

            'ign' =>
                "📝 برای ادامه ثبت‌نام <b>{$event}</b> فقط کافیه IGN خودت رو وارد کنی.",

            'game_id' =>
                "🆔 ثبت‌نام <b>{$event}</b> تقریباً آماده‌ست؛ فقط Game ID رو وارد کن.",

            'referral' =>
                "👥 برای تکمیل ثبت‌نام <b>{$event}</b>، فقط <b>{$remainingReferralsText}</b> دعوت دیگه لازمه.",

            'force_join' =>
                "📢 برای ادامه ثبت‌نام <b>{$event}</b>، عضویت در کانال‌های موردنیاز رو تکمیل کن.",

            'payment' =>
                "💳 ثبت‌نام <b>{$event}</b> تقریباً تکمیل شده؛ فقط مرحله پرداخت باقی مونده.",

            default => null
        },

        'normal' => match ($step) {
            'start' =>
                "🎮 ثبت‌نام <b>{$event}</b> هنوز تکمیل نشده؛ می‌تونی همین حالا ادامه‌ش بدی.",

            'ign' =>
                "📝 ثبت‌نام <b>{$event}</b> متوقف شده؛ برای ادامه، IGN خودت رو وارد کن.",

            'game_id' =>
                "🆔 برای ادامه ثبت‌نام <b>{$event}</b>، Game ID خودت رو وارد کن.",

            'referral' =>
                "👥 هنوز یک مرحله تا تکمیل ثبت‌نام <b>{$event}</b> باقی مونده؛ دعوت دوستانت رو کامل کن.",

            'force_join' =>
                "📢 برای ادامه ثبت‌نام <b>{$event}</b>، عضویت در کانال‌های موردنیاز رو تکمیل کن.",

            'payment' =>
                "💳 ثبت‌نام <b>{$event}</b> هنوز تکمیل نشده؛ پرداخت رو انجام بده تا ثبت‌نامت نهایی بشه.",

            default => null
        },

        'urgent' => match ($step) {
            'start' =>
                "🚨 ثبت‌نام <b>{$event}</b> هنوز تکمیل نشده؛ اگر قصد شرکت داری، بهتره همین حالا ادامه بدی.",

            'ign' =>
                "⚠️ ثبت‌نام <b>{$event}</b> در انتظار ثبت IGN شماست؛ همین حالا این مرحله رو تکمیل کن.",

            'game_id' =>
                "⚠️ برای نهایی شدن ثبت‌نام <b>{$event}</b>، Game ID هنوز ثبت نشده؛ همین حالا واردش کن.",

            'referral' =>
                "🚨 تکمیل ثبت‌نام <b>{$event}</b> به <b>{$remainingReferralsText}</b> دعوت دیگه نیاز داره؛ فرصت رو از دست نده.",

            'force_join' =>
                "🚨 برای ادامه ثبت‌نام <b>{$event}</b>، عضویت در کانال‌های موردنیاز باید تکمیل بشه.",

            'payment' =>
                "🚨 ثبت‌نام <b>{$event}</b> هنوز نهایی نشده؛ برای از دست ندادن فرصت شرکت، پرداخت رو همین حالا تکمیل کن.",

            default => null
        },

        default => null
    };


    }

    private function log(string $message, array $context = []): void
    {
        $line = '[' . date('Y-m-d H:i:s') . '] ' . $message;

        if (!empty($context)) {
            $line .= ' | ' . json_encode($context, JSON_UNESCAPED_UNICODE);
        }

        $line .= PHP_EOL;

        file_put_contents(
            dirname(__DIR__) . '/storage/reminder.log',
            $line,
            FILE_APPEND | LOCK_EX
        );
    }

    private function buildCtaKeyboard(array $row, string $step, string $type): ?array
    {
        $stepDefinitions = self::CTA_DEFINITIONS[$step] ?? null;
        $definition = $stepDefinitions[$type] ?? ($stepDefinitions['normal'] ?? null);

        if (!$definition) {
            return null;
        }

        $eventId = (int)($row['event_id'] ?? 0);
        $userId = (int)($row['user_id'] ?? 0);

        $callbackData = sprintf(
            $definition['callback'],
            $eventId,
            $userId
        );

        $callbackData .= ':reminder';

        $this->log(
            "REMINDER CALLBACK => " . $callbackData
        );

        return [
            'inline_keyboard' => [[
                [
                    'text' => $definition['label'],
                    'callback_data' => $callbackData,
                    'style' => 'primary',
                ],
            ]],
        ];
    }


    private function sendTelegram(int $userId, string $text, ?array $replyMarkup = null): bool
    {
        $botToken = $_ENV['BOT_TOKEN'] ?? null;

        if (!$botToken) {
            $this->log('BOT TOKEN missing');
            return false;
        }

        $url = "https://api.telegram.org/bot{$botToken}/sendMessage";

        $data = [
            'chat_id' => $userId,
            'text' => $text,
            'parse_mode' => 'HTML',
        ];

        if ($replyMarkup !== null) {
            $data['reply_markup'] = json_encode($replyMarkup, JSON_UNESCAPED_UNICODE);
        }

        $ch = curl_init();

        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
        ]);

        $response = curl_exec($ch);

        if ($response === false) {
            $this->log('Curl Error: ' . curl_error($ch));
            curl_close($ch);
            return false;
        }

        curl_close($ch);

        $result = json_decode($response, true);

        if (!($result['ok'] ?? false)) {
            $this->log('Telegram Error: ' . $response);
            return false;
        }

        $this->log("Reminder sent to {$userId}");

        return true;
    }
}