<?php
namespace Core\Services;
use Core\Database;

/**
 * TelegramBotService — Secure Arabic NLP Command Engine for OTIS
 *
 * Security model:
 *  - Validates chat_id against TELEGRAM_ALLOWED_CHAT_ID (single-user)
 *  - Webhook secret token checked on every request
 *  - No session, no cookies — pure stateless token-auth
 *
 * Adding new commands:
 *  1. Add pattern to $commandPatterns
 *  2. Add handler method handle_*()
 *  3. Done
 */
class TelegramBotService {

    private $token;
    private $allowedChatId;
    private $otisUserId;
    private $db;

    // ── Arabic NLP Pattern Registry ────────────────────────────
    private $commandPatterns = [
        // EXPENSE: "صرفت 50 قهوة" | "دفعت 120 مواصلات"
        ['regex' => '/^(صرفت|دفعت|أنفقت|انفقت)\s+(\d+(?:\.\d+)?)\s+(.+)$/u', 'command' => 'add_expense'],

        // TASK: "أضف مهمة راجع الملف" | "مهمة جديدة اتصل بالدكتور"
        ['regex' => '/^(أضف مهمة|اضف مهمة|مهمة جديدة|مهمة)\s+(.+)$/u', 'command' => 'add_task'],

        // DONE TASK: "أنهيت مهمة الاتصال" | "خلصت مهمة المشروع"
        ['regex' => '/^(أنهيت|انهيت|خلصت|أكملت|انتهيت من)\s+(?:مهمة\s+)?(.+)$/u', 'command' => 'done_task'],

        // HABIT: "سجل عادة قراءة" | "أتممت عادة التمرين"
        ['regex' => '/^(سجل عادة|أتممت عادة|انهيت عادة|اتممت عادة)\s+(.+)$/u', 'command' => 'log_habit'],

        // NOTE: "ملاحظة: فكرة رائعة للمشروع"
        ['regex' => '/^(ملاحظة|نوت|note)[:\s]+(.+)$/ui', 'command' => 'add_note'],

        // STATUS: "وضعي" | "حالتي" | "تقريري"
        ['regex' => '/^(وضعي|حالتي|تقريري|status|ملخص)$/ui', 'command' => 'get_status'],

        // HELP: "مساعدة" | "help"
        ['regex' => '/^(مساعدة|help|الأوامر)$/ui', 'command' => 'help'],
    ];

    // ── Arabic → Finance Category Mapping ──────────────────────
    private $categoryMap = [
        // Food
        'قهوة' => 'طعام وشراب', 'أكل' => 'طعام وشراب', 'اكل' => 'طعام وشراب',
        'مطعم' => 'طعام وشراب', 'فطار' => 'طعام وشراب', 'غداء' => 'طعام وشراب',
        'عشاء' => 'طعام وشراب', 'شاي' => 'طعام وشراب', 'طعام' => 'طعام وشراب',

        // Transport
        'مواصلات' => 'مواصلات', 'أوبر' => 'مواصلات', 'تاكسي' => 'مواصلات',
        'بنزين' => 'مواصلات', 'كريم' => 'مواصلات', 'باص' => 'مواصلات',

        // Health
        'دواء' => 'صحة', 'دكتور' => 'صحة', 'صيدلية' => 'صحة', 'طبيب' => 'صحة',

        // Shopping
        'تسوق' => 'تسوق', 'ملابس' => 'تسوق', 'كتاب' => 'تعليم', 'كورس' => 'تعليم',

        // Bills
        'فاتورة' => 'فواتير', 'إيجار' => 'فواتير', 'كهرباء' => 'فواتير',

        // Default
        '_default' => 'متنوع',
    ];

    public function __construct() {
        $this->db = Database::getInstance();
        $env = $this->loadEnv();
        $this->token         = $env['TELEGRAM_BOT_TOKEN']         ?? '';
        $this->allowedChatId = (string)($env['TELEGRAM_ALLOWED_CHAT_ID'] ?? '');
        $this->otisUserId    = (int)($env['TELEGRAM_OTIS_USER_ID']    ?? 1);
    }

    private function loadEnv(): array {
        $envFile = ROOT_PATH . '/config/.env';
        $env = [];
        if (!file_exists($envFile)) return $env;
        foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
            if (str_starts_with(trim($line), '#') || !str_contains($line, '=')) continue;
            [$k, $v] = explode('=', $line, 2);
            $env[trim($k)] = trim($v);
        }
        return $env;
    }

    // =========================================================
    // MAIN WEBHOOK HANDLER
    // =========================================================
    public function handleWebhook(): void {
        // 1. Parse Telegram payload
        $input = file_get_contents('php://input');
        $update = json_decode($input, true);

        if (!$update || !isset($update['message'])) {
            http_response_code(200); // Always 200 to Telegram
            exit;
        }

        $message = $update['message'];
        $chatId  = (string)($message['chat']['id'] ?? '');
        $text    = trim($message['text'] ?? '');

        // 2. Security Gate — reject unknown senders immediately
        if ($chatId !== $this->allowedChatId) {
            $this->sendMessage($chatId, '⛔ وصول مرفوض. هذا البوت خاص.');
            http_response_code(200);
            exit;
        }

        if (empty($text)) {
            $this->sendMessage($chatId, '📝 أرسل رسالة نصية لأتمكن من معالجتها.');
            http_response_code(200);
            exit;
        }

        // 3. Match command
        $matched = false;
        foreach ($this->commandPatterns as $pattern) {
            if (preg_match($pattern['regex'], $text, $matches)) {
                $handler = 'handle_' . $pattern['command'];
                if (method_exists($this, $handler)) {
                    $reply = $this->$handler($matches);
                    $this->sendMessage($chatId, $reply);
                    $matched = true;
                }
                break;
            }
        }

        if (!$matched) {
            $this->sendMessage($chatId,
                "❓ لم أفهم طلبك.\n\nأرسل *مساعدة* لرؤية قائمة الأوامر.",
            );
        }

        http_response_code(200);
        exit;
    }

    // =========================================================
    // COMMAND HANDLERS
    // =========================================================

    private function handle_add_expense(array $m): string {
        $amount   = (float)$m[2];
        $rawItem  = trim($m[3]);
        $category = $this->detectCategory($rawItem);

        try {
            $this->db->query(
                "INSERT INTO finance_expenses (user_id, category, item_name, amount, expense_date, created_at)
                 VALUES (?, ?, ?, ?, CURDATE(), NOW())",
                [$this->otisUserId, $category, $rawItem, $amount]
            );

            // Gamification
            require_once ROOT_PATH . '/core/Services/GamificationEngine.php';
            GamificationEngine::getInstance()->onEvent('finance_logged', $this->otisUserId);

            // Smart feedback
            $feedback = $this->getFinanceFeedback($amount);

            return "✅ تم تسجيل المصروف\n" .
                   "━━━━━━━━━━━━━━━\n" .
                   "💰 المبلغ: {$amount} ج.م\n" .
                   "🏷 الصنف: {$rawItem}\n" .
                   "📂 الفئة: {$category}\n" .
                   ($feedback ? "\n{$feedback}" : "");

        } catch (\Exception $e) {
            error_log('[TelegramBot] add_expense error: ' . $e->getMessage());
            return '❌ حدث خطأ أثناء تسجيل المصروف، يرجى المحاولة لاحقاً.';
        }
    }

    private function handle_add_task(array $m): string {
        $title = trim($m[2]);

        try {
            $this->db->query(
                "INSERT INTO todo_tasks (user_id, title, category, priority, status, target_date, created_at)
                 VALUES (?, ?, 'عام', 'medium', 'pending', CURDATE(), NOW())",
                [$this->otisUserId, $title]
            );

            return "✅ تم إضافة المهمة\n" .
                   "━━━━━━━━━━━━━━━\n" .
                   "📋 المهمة: {$title}\n" .
                   "📅 لليوم: " . date('Y-m-d') . "\n\n" .
                   "💡 افتح /todo لإدارة مهامك.";

        } catch (\Exception $e) {
            return '❌ فشل إضافة المهمة.';
        }
    }

    private function handle_done_task(array $m): string {
        $titleSearch = '%' . trim($m[2]) . '%';

        $task = $this->db->query(
            "SELECT id, title FROM todo_tasks WHERE user_id=? AND status='pending' AND title LIKE ? ORDER BY created_at DESC LIMIT 1",
            [$this->otisUserId, $titleSearch]
        )->fetch();

        if (!$task) {
            return "❓ لم أجد مهمة معلقة تطابق: *{$m[2]}*\n\nتأكد من اسم المهمة أو راجع قائمتك.";
        }

        $this->db->query(
            "UPDATE todo_tasks SET status='done', updated_at=NOW() WHERE id=?",
            [$task->id]
        );

        // Gamification
        require_once ROOT_PATH . '/core/Services/GamificationEngine.php';
        GamificationEngine::getInstance()->onEvent('task_completed', $this->otisUserId);

        return "🏆 أحسنت! تم إنجاز المهمة\n" .
               "━━━━━━━━━━━━━━━\n" .
               "✅ {$task->title}\n\n" .
               "⚡ حصلت على نقاط XP! استمر يا بطل.";
    }

    private function handle_log_habit(array $m): string {
        $habitSearch = '%' . trim($m[2]) . '%';

        $habit = $this->db->query(
            "SELECT id, name FROM habits WHERE user_id=? AND deleted_at IS NULL AND name LIKE ? LIMIT 1",
            [$this->otisUserId, $habitSearch]
        )->fetch();

        if (!$habit) {
            return "❓ لم أجد عادة تطابق: *{$m[2]}*\n\nراجع عاداتك على /habits.";
        }

        // Check already logged
        $alreadyLogged = $this->db->query(
            "SELECT COUNT(*) FROM habit_logs WHERE habit_id=? AND user_id=? AND log_date=CURDATE()",
            [$habit->id, $this->otisUserId]
        )->fetchColumn();

        if ($alreadyLogged) {
            return "ℹ️ لقد سجّلت عادة *{$habit->name}* بالفعل اليوم! 👍";
        }

        $this->db->query(
            "INSERT INTO habit_logs (habit_id, user_id, log_date, created_at) VALUES (?, ?, CURDATE(), NOW())",
            [$habit->id, $this->otisUserId]
        );

        // Gamification
        require_once ROOT_PATH . '/core/Services/GamificationEngine.php';
        GamificationEngine::getInstance()->onEvent('habit_done', $this->otisUserId);

        return "🔥 تم تسجيل العادة\n" .
               "━━━━━━━━━━━━━━━\n" .
               "✅ {$habit->name}\n" .
               "📅 " . date('Y-m-d') . "\n\n" .
               "⚡ +5 XP — حافظ على سلسلتك!";
    }

    private function handle_add_note(array $m): string {
        $content = trim($m[2]);

        try {
            $this->db->query(
                "INSERT INTO todo_tasks (user_id, title, category, priority, status, target_date, created_at)
                 VALUES (?, ?, 'ملاحظات', 'low', 'pending', CURDATE(), NOW())",
                [$this->otisUserId, "📝 " . $content]
            );

            return "📝 تم حفظ الملاحظة\n━━━━━━━━━━━━━━━\n{$content}";
        } catch (\Exception $e) {
            return '❌ فشل حفظ الملاحظة.';
        }
    }

    private function handle_get_status(array $m): string {
        // Tasks today
        $done    = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status='done' AND target_date=CURDATE() AND deleted_at IS NULL", [$this->otisUserId])->fetchColumn();
        $pending = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status='pending' AND target_date=CURDATE() AND deleted_at IS NULL", [$this->otisUserId])->fetchColumn();

        // Finance today
        $spent = $this->db->query("SELECT COALESCE(SUM(amount),0) FROM finance_expenses WHERE user_id=? AND expense_date=CURDATE() AND deleted_at IS NULL", [$this->otisUserId])->fetchColumn();

        // Habits today
        $habitsLogged = $this->db->query("SELECT COUNT(DISTINCT habit_id) FROM habit_logs WHERE user_id=? AND log_date=CURDATE() AND deleted_at IS NULL", [$this->otisUserId])->fetchColumn();

        // XP
        $xp    = $this->db->query("SELECT xp_points FROM user_xp WHERE user_id=?", [$this->otisUserId])->fetchColumn() ?? 0;
        $level = $this->db->query("SELECT level FROM user_xp WHERE user_id=?", [$this->otisUserId])->fetchColumn() ?? 1;

        $taskBar = $this->progressBar($done, $done + $pending);

        return "📊 *تقرير اليوم — " . date('Y-m-d') . "*\n" .
               "━━━━━━━━━━━━━━━━━━━━\n" .
               "✅ المهام: {$done} منجزة من " . ($done + $pending) . "\n" .
               "{$taskBar}\n\n" .
               "🔥 العادات اليوم: {$habitsLogged} مسجّلة\n" .
               "💰 الإنفاق: " . number_format($spent, 0) . " ج.م\n" .
               "⚡ مستواك: {$level} | {$xp} XP\n\n" .
               ($pending > 0 ? "💡 لديك {$pending} مهمة معلقة، انجزها!" : "🏆 أتممت كل مهامك اليوم!");
    }

    private function handle_help(array $m): string {
        return "🤖 *أوامر بوت OTIS*\n" .
               "━━━━━━━━━━━━━━━━━━━━\n\n" .
               "💰 *مصروف:*\n" .
               "  صرفت 50 قهوة\n" .
               "  دفعت 120 مواصلات\n\n" .
               "📋 *مهمة:*\n" .
               "  مهمة جديدة: مراجعة التقرير\n" .
               "  أضف مهمة الاتصال بالعميل\n\n" .
               "✅ *إنجاز مهمة:*\n" .
               "  أنهيت مهمة المراجعة\n" .
               "  خلصت مهمة التقرير\n\n" .
               "🔥 *تسجيل عادة:*\n" .
               "  سجل عادة قراءة\n" .
               "  أتممت عادة التمرين\n\n" .
               "📝 *ملاحظة:*\n" .
               "  ملاحظة: فكرة جديدة\n\n" .
               "📊 *التقرير:*\n" .
               "  وضعي\n" .
               "  حالتي";
    }

    // =========================================================
    // SMART FEEDBACK
    // =========================================================
    private function getFinanceFeedback(float $amount): string {
        // Compare to average daily spend
        $avgDaily = $this->db->query(
            "SELECT COALESCE(AVG(daily_total), 0) FROM (
                SELECT SUM(amount) AS daily_total FROM finance_expenses
                WHERE user_id=? AND expense_date BETWEEN DATE_SUB(CURDATE(),INTERVAL 30 DAY) AND CURDATE()
                AND deleted_at IS NULL GROUP BY expense_date
            ) t",
            [$this->otisUserId]
        )->fetchColumn();

        $todayTotal = $this->db->query(
            "SELECT COALESCE(SUM(amount),0) FROM finance_expenses WHERE user_id=? AND expense_date=CURDATE() AND deleted_at IS NULL",
            [$this->otisUserId]
        )->fetchColumn();

        if ($avgDaily > 0 && $todayTotal > $avgDaily * 2) {
            return "⚠️ *تنبيه:* إنفاقك اليوم (" . number_format($todayTotal, 0) . " ج.م) يتجاوز ضعف معدلك اليومي المعتاد (" . number_format($avgDaily, 0) . " ج.م). انتبه!";
        }

        if ($amount >= 200) {
            return "💡 مصروف كبير نسبياً — هل هو ضروري؟ فكّر قبل الإنفاق التالي.";
        }

        return '';
    }

    private function detectCategory(string $item): string {
        $item = mb_strtolower($item, 'UTF-8');
        foreach ($this->categoryMap as $keyword => $cat) {
            if ($keyword === '_default') continue;
            if (str_contains($item, $keyword)) {
                return $cat;
            }
        }
        return $this->categoryMap['_default'];
    }

    private function progressBar(int $done, int $total): string {
        if ($total === 0) return '░░░░░░░░░░ 0%';
        $pct    = (int)(($done / $total) * 10);
        $filled = str_repeat('█', $pct);
        $empty  = str_repeat('░', 10 - $pct);
        return "{$filled}{$empty} " . round(($done / $total) * 100) . '%';
    }

    // =========================================================
    // TELEGRAM API — Send Message
    // =========================================================
    private function sendMessage(string $chatId, string $text): void {
        if (empty($this->token)) return;

        $url  = "https://api.telegram.org/bot{$this->token}/sendMessage";
        $data = [
            'chat_id'    => $chatId,
            'text'       => $text,
            'parse_mode' => 'Markdown',
        ];

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($data),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_SSL_VERIFYPEER => true,
        ]);
        curl_exec($ch);
        curl_close($ch);
    }
}
