# -*- coding: utf-8 -*-
"""
bitpay_gateway.py
==================
ماژول مستقل و اضافه‌شده برای اتصال به درگاه پرداخت (طبق مستندات ارائه‌شده).
این فایل به ساختار و منطق اصلی ربات (yas.py) دست نمی‌زند؛ فقط توابع لازم
برای «ایجاد تراکنش»، «تایید تراکنش» و دریافت «بازگشت از درگاه (Callback)»
را فراهم می‌کند تا از داخل yas.py صدا زده شوند.

نکات مهم بر اساس مستندات:
- آدرس پایه API:            https://www.safronakbari.ir/api/
- واحد پول در API:          ریال (بنابراین مبالغ تومانی ربات باید ضربدر ۱۰ شوند)
- حداقل مبلغ قابل پرداخت:   ۵۰۰۰ ریال (۵۰۰ تومان)
- verify_transaction نیازمند trans_id است که فقط از طریق callback.php
  (بعد از بازگشت کاربر از درگاه) در دسترس قرار می‌گیرد؛ به همین دلیل یک
  وب‌سرور سبک (Flask) برای دریافت این callback در همین فایل پیاده‌سازی شده.
"""

import logging
import requests
from flask import Flask, request

API_BASE = "https://www.safronakbari.ir/api"

CREATE_TRANSACTION_URL = f"{API_BASE}/create_transaction.php"
VERIFY_TRANSACTION_URL = f"{API_BASE}/verify_transaction.php"

# کدهای خطای مستند شده در مستندات، برای نمایش پیام بهتر به کاربر
ERROR_CODES = {
    1: "API ارسالی معتبر نیست",
    2: "مبلغ نامعتبر یا کمتر از حد مجاز است",
    3: "آدرس بازگشتی نامعتبر است",
    4: "درگاهی با این اطلاعات وجود ندارد",
    5: "خطا در اتصال به درگاه، لطفاً مجدد تلاش کنید",
}


def _post(url, payload):
    """ارسال درخواست POST با JSON طبق مستندات و مدیریت خطاها."""
    try:
        resp = requests.post(
            url,
            json=payload,
            headers={"Content-Type": "application/json"},
            timeout=20,
        )
        resp.raise_for_status()
        return resp.json()
    except requests.exceptions.RequestException as e:
        logging.error(f"[bitpay_gateway] Network error calling {url}: {e}")
        return {"status": False, "message": "خطا در اتصال به درگاه پرداخت", "error_code": 5}
    except ValueError as e:
        logging.error(f"[bitpay_gateway] Invalid JSON response from {url}: {e}")
        return {"status": False, "message": "پاسخ نامعتبر از درگاه پرداخت"}


def create_transaction(amount_toman, factor_id=None, name=None, email=None,
                        description=None, mobile=None, card_num=None):
    """
    ایجاد تراکنش جدید (مطابق بخش «۱. ایجاد تراکنش جدید» مستندات).
    amount_toman: مبلغ به تومان (در ربات استفاده می‌شود) -> در درخواست به ریال تبدیل می‌شود.
    خروجی: دیکشنری پاسخ API شامل status, payment_url, id_get (در صورت موفقیت).
    """
    payload = {"amount": int(amount_toman) * 10}  # تبدیل تومان به ریال
    if factor_id:
        payload["factorId"] = factor_id
    if name:
        payload["name"] = name
    if email:
        payload["email"] = email
    if description:
        payload["description"] = description
    if mobile:
        payload["mobile"] = mobile
    if card_num:
        payload["cardNum"] = card_num

    result = _post(CREATE_TRANSACTION_URL, payload)
    if not result.get("status") and result.get("error_code") in ERROR_CODES:
        result["message"] = ERROR_CODES[result["error_code"]]
    return result


def verify_transaction(trans_id, id_get):
    """
    تایید تراکنش (مطابق بخش «۲. تایید تراکنش» مستندات).
    trans_id و id_get از پارامترهای callback دریافت می‌شوند.
    خروجی: دیکشنری شامل status و در صورت موفقیت data.status (۱=موفق، ۱۱=قبلا تایید شده).
    """
    payload = {"trans_id": trans_id, "id_get": id_get}
    return _post(VERIFY_TRANSACTION_URL, payload)


def create_callback_app(on_result):
    """
    ساخت اپ Flask برای دریافت بازگشت از درگاه (مطابق بخش «۳. بازگشت از درگاه (Callback)»).
    آدرس دقیقاً مطابق مستندات پیاده‌سازی شده: GET /callback?trans_id=...&id_get=...

    on_result(id_get, trans_id, success: bool, verify_result: dict) پس از تایید صدا زده می‌شود
    تا ربات بتواند کیف پول کاربر را شارژ کند / سفارش را نهایی کند و به او در تلگرام اطلاع دهد.
    """
    app = Flask(__name__)

    page_style = (
        "font-family:Tahoma,Arial,sans-serif;text-align:center;"
        "padding-top:60px;direction:rtl"
    )

    @app.route("/callback", methods=["GET"])
    def callback():
        trans_id = request.args.get("trans_id")
        id_get = request.args.get("id_get")

        if not trans_id or not id_get:
            return f"<html><body style='{page_style}'><h2>❌ پارامترهای ناقص</h2></body></html>", 400

        verify_result = verify_transaction(trans_id, id_get)
        data = verify_result.get("data", {}) or {}
        success = bool(verify_result.get("status")) and data.get("status") in (1, 11)

        try:
            on_result(id_get, trans_id, success, verify_result)
        except Exception as e:
            logging.error(f"[bitpay_gateway] on_result callback error: {e}")

        if success:
            return (
                f"<html><body style='{page_style}'>"
                f"<h2>✅ پرداخت با موفقیت انجام شد</h2>"
                f"<p>می‌توانید به ربات تلگرام بازگردید.</p>"
                f"</body></html>"
            )
        return (
            f"<html><body style='{page_style}'>"
            f"<h2>❌ پرداخت ناموفق بود</h2>"
            f"<p>{verify_result.get('message', '')}</p>"
            f"</body></html>"
        )

    return app


def run_callback_server(app, host="0.0.0.0", port=5005):
    """اجرای وب‌سرور دریافت callback (باید در یک ترد جداگانه اجرا شود)."""
    app.run(host=host, port=port)
