import time
from sqlalchemy.orm import Session

from app.services.transaction_service import (
    get_transaction_by_payme_id,
    create_transaction,
    update_transaction_state,
)
from app.services.shopify_service import mark_order_paid, get_shopify_order
from app.core.constants import (
    STATE_CREATED,
    STATE_COMPLETED,
    STATE_CANCELLED,
    ERROR_TRANSACTION_NOT_FOUND,
)


async def check_perform_transaction(params: dict) -> dict:
    order_id = params["account"]["order"]
    payme_amount = params["amount"]  # tiyin

    order = await get_shopify_order(order_id)

    if not order:
        return {"allow": False}

    # Draft orders use "total_price", completed orders too — same field name
    shopify_amount = int(float(order["total_price"]) * 100)

    if shopify_amount != payme_amount:
        return {"allow": False}

    # Draft: status field is "status" not "financial_status"
    if order.get("_is_draft"):
        already_paid = order.get("status") == "completed"
    else:
        already_paid = order.get("financial_status") == "paid"

    if already_paid:
        return {"allow": False}

    return {"allow": True}


async def create_transaction_handler(db: Session, params: dict) -> dict:
    payme_id = params["id"]
    order_id = params["account"]["order"]
    amount = params["amount"]

    existing = get_transaction_by_payme_id(db, payme_id)
    if existing:
        return {
            "create_time": int(time.time() * 1000),
            "transaction": payme_id,
            "state": existing.state,
        }

    create_transaction(db, order_id, payme_id, amount)

    return {
        "create_time": int(time.time() * 1000),
        "transaction": payme_id,
        "state": STATE_CREATED,
    }


async def perform_transaction_handler(db: Session, params: dict) -> dict | None:
    payme_id = params["id"]

    transaction = get_transaction_by_payme_id(db, payme_id)
    if not transaction:
        return None

    if transaction.state == STATE_COMPLETED:
        return {
            "perform_time": int(time.time() * 1000),
            "transaction": payme_id,
            "state": STATE_COMPLETED,
        }

    update_transaction_state(db, transaction, STATE_COMPLETED)

    # Fetch order to know if it's a draft
    order = await get_shopify_order(transaction.order_id)
    is_draft = order.get("_is_draft", False) if order else False

    amount_uzs = str(transaction.amount / 100)
    await mark_order_paid(transaction.order_id, amount_uzs, is_draft=is_draft)

    return {
        "perform_time": int(time.time() * 1000),
        "transaction": payme_id,
        "state": STATE_COMPLETED,
    }


async def cancel_transaction_handler(db: Session, params: dict) -> dict | None:
    payme_id = params["id"]

    transaction = get_transaction_by_payme_id(db, payme_id)
    if not transaction:
        return None

    update_transaction_state(db, transaction, STATE_CANCELLED)

    return {
        "cancel_time": int(time.time() * 1000),
        "transaction": payme_id,
        "state": STATE_CANCELLED,
    }