<?php

namespace App\Core\Flows;

use App\Services\SiroService;

/**
 * PaymentFlow — Smart Payment Verification
 *
 * Flow: start → await_receipt → finished
 *
 * Smart features:
 *   • Auto-detects country + payment method (shamcash/cliq)
 *   • Auto-finds pending invoice by phone (no invoice number needed)
 *   • AI receipt verification via payment server Gemini
 *   • Postponement detection (keyword-based)
 *   • Image validation + retry (max 3 attempts)
 *   • Currency-aware messages (SYP/JOD)
 */
class PaymentFlow extends BaseFlow
{
    private const MAX_RETRIES = 3;

    public function handleStep(string $step, array $messageData, array &$context): FlowResult
    {
        $phone = $messageData['phone'] ?? '';
        $text  = isset($messageData['body']) ? trim($messageData['body']) : '';
        $image = $messageData['image'] ?? '';
        $imageMimeType = $messageData['imageMimeType'] ?? 'image/jpeg';

        // ── Postponement check (only if flow is active, not on start/finished) ──
        if ($step !== 'start' && $step !== 'finished' && !empty($text)) {
            $postpone = $this->detectPostponement($text);
            if ($postpone !== null) {
                $context['previous_step'] = $step;
                $hours = $postpone;
                return new FlowResult(
                    "حاضر كابتن، تم تأجيل طلب الدفع. سأذكرك بعد {$hours} ساعات.\n"
                    . "للمتابعة لاحقاً، أرسل 'دفع' مرة أخرى.",
                    "postponed"
                );
            }
        }

        // ── Country + method detection ──
        $country = $context['country'] ?? SiroService::detectCountry($phone);
        $context['country'] = $country;

        $paymentMethod = $context['payment_method'] ?? match ($country) {
            'jordan' => 'cliq',
            default  => 'shamcash',
        };
        $context['payment_method'] = $paymentMethod;

        $methodName  = $paymentMethod === 'cliq' ? 'كليك (Cliq)' : 'شام كاش (ShamCash)';
        $currency    = $paymentMethod === 'cliq' ? 'دينار أردني' : 'ل.س';
        $countryName = match ($country) {
            'jordan' => 'الأردن',
            'egypt'  => 'مصر',
            default  => 'سوريا',
        };

        switch ($step) {
            // ─────────────────────────────────────────────────
            // START
            // ─────────────────────────────────────────────────
            case 'start':
                $context['retry_count'] = 0;

                return new FlowResult(
                    "أهلاً بك في خدمة التحقق من الدفع.\n\n"
                    . "📍 الدولة: {$countryName}\n"
                    . "💰 طريقة الدفع: {$methodName}\n"
                    . "💵 العملة: {$currency}\n\n"
                    . "📸 يرجى إرسال صورة واضحة لإيصال الدفع أو صورة الشاشة.\n"
                    . "سيتم التحقق من الفاتورة المعلقة تلقائياً.\n\n"
                    . "🟡 للخروج اكتب: إلغاء\n"
                    . "⏰ للتأجيل اكتب: بعدين",
                    "await_receipt"
                );

            // ─────────────────────────────────────────────────
            // AWAIT_RECEIPT
            // ─────────────────────────────────────────────────
            case 'await_receipt':
                // ── No image sent ──
                if (empty($image)) {
                    return new FlowResult(
                        "📸 يرجى إرسال صورة الإيصال أو وصل التحويل.\n"
                        . "تأكد من أن الصورة واضحة وتظهر المبلغ وتفاصيل التحويل.",
                        "await_receipt"
                    );
                }

                // ── Validate image size ──
                $decoded = base64_decode($image, true);
                if ($decoded === false || strlen($decoded) < 1024) {
                    $retry = ($context['retry_count'] ?? 0) + 1;
                    $context['retry_count'] = $retry;

                    if ($retry >= self::MAX_RETRIES) {
                        return new FlowResult(
                            "عذراً، لم نتمكن من قراءة الصورة بعد {$retry} محاولات.\n"
                            . "يرجى التواصل مع خدمة العملاء لإتمام عملية الدفع يدوياً.",
                            "finished",
                            true
                        );
                    }

                    return new FlowResult(
                        "⚠️ الصورة غير واضحة أو صغيرة جداً.\n"
                        . "يرجى إرسال صورة واضحة وحجم أكبر (محاولة {$retry} من " . self::MAX_RETRIES . "):",
                        "await_receipt"
                    );
                }

                // ── Normalize MIME type ──
                if (strpos($imageMimeType, ';') !== false) {
                    $imageMimeType = trim(explode(';', $imageMimeType)[0]);
                }

                // ── Send to payment server ──
                $companyId = $context['company_id'] ?? 1;

                $result = \App\Controllers\WhatsAppController::verifyPaymentSlipStatic(
                    companyId: $companyId,
                    phone: $phone,
                    jsonStr: '',
                    userType: 'driver',
                    paymentMethod: $paymentMethod,
                    invoiceNumber: '',
                    receiptImage: $image,
                    imageMimeType: $imageMimeType,
                );

                if ($result) {
                    return new FlowResult($result, "finished", true);
                }

                $retry = ($context['retry_count'] ?? 0) + 1;
                $context['retry_count'] = $retry;

                if ($retry >= self::MAX_RETRIES) {
                    return new FlowResult(
                        "عذراً، تعذر التحقق من الدفع بعد {$retry} محاولات.\n"
                        . "سيتم مراجعة العملية من قبل الإدارة.",
                        "finished",
                        true
                    );
                }

                return new FlowResult(
                    "لم نتمكن من التحقق من الدفع حالياً (محاولة {$retry} من " . self::MAX_RETRIES . ").\n"
                    . "يرجى إرسال صورة أوضح والإضاءة جيدة:",
                    "await_receipt"
                );

            case 'postponed':
                // Resume from postponed
                $step = $context['previous_step'] ?? 'await_receipt';
                return new FlowResult(
                    "مرحباً بك مرة أخرى! 👋\n"
                    . "📸 أرسل صورة إيصال الدفع للمتابعة:",
                    $step
                );

            default:
                return new FlowResult("حدث خطأ في المسار.", "finished", true);
        }
    }

    /**
     * Detect if user wants to postpone (keyword-based, no AI call)
     */
    private function detectPostponement(string $text): ?int
    {
        $keywords = [
            'بعدين' => 2, 'بكرا' => 12, 'بكرة' => 12, 'بعد' => 3,
            'شوي' => 1, 'مشغول' => 4, 'تأجيل' => 6, 'لاحقاً' => 6,
            'لاحقا' => 6, 'الحق' => 6, 'وقت ثاني' => 8, 'تعبان' => 6,
            'بعدين برسل' => 3, 'بعدين ببعت' => 3, 'بعدين بكمل' => 4,
            'ببعثها' => 3, 'ببعت' => 3, 'برسل' => 2,
        ];

        $normalized = trim(mb_strtolower($text));
        foreach ($keywords as $kw => $hours) {
            if (mb_strpos($normalized, $kw) !== false) {
                return $hours;
            }
        }

        return null;
    }
}
