"""
Клиент для работы с AuroraPay Payment API
"""

import requests
from typing import Optional
from .models import CreateOrderRequest, CreateOrderResponse, PaymentStatusResponse
from .exceptions import (
    AuroraPayError,
    ValidationError,
    OrderCreationError,
    OrderNotFoundError,
    UnauthorizedError,
    InactiveShopError,
    ForbiddenError,
)


class AuroraPayClient:
    """
    Клиент для работы с AuroraPay Payment API
    
    Пример использования:
        client = AuroraPayClient(api_key="your_api_key_here")
        
        # Создать заказ
        order = client.create_order(amount=5000, payment_method="card")
        print(f"Order ID: {order.order_id}")
        print(f"Payment Link: {order.payment_link}")
        
        # Проверить статус
        status = client.get_payment_status(order.order_id)
        print(f"Status: {status.status}")
    """
    
    def __init__(
        self,
        api_key: str,
        base_url: str = "https://goiskra.com",
        timeout: int = 30
    ):
        """
        Инициализация клиента
        
        Args:
            api_key: API ключ для аутентификации
            base_url: Базовый URL API (по умолчанию: https://goiskra.com)
            timeout: Таймаут запросов в секундах (по умолчанию: 30)
        """
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            "X-API-Key": self.api_key,
            "Content-Type": "application/json",
        })
    
    def _handle_error(self, response: requests.Response) -> None:
        """Обработка ошибок API"""
        try:
            error_data = response.json()
            error = error_data.get("error", {})
            code = error.get("code", "UNKNOWN_ERROR")
            message = error.get("message", "Unknown error occurred")
        except Exception:
            code = "UNKNOWN_ERROR"
            message = f"HTTP {response.status_code}: {response.text}"
        
        # Маппинг кодов ошибок на исключения
        error_map = {
            "VALIDATION_ERROR": ValidationError,
            "ORDER_CREATION_FAILED": OrderCreationError,
            "ORDER_NOT_FOUND": OrderNotFoundError,
            "UNAUTHORIZED": UnauthorizedError,
            "INACTIVE_SHOP": InactiveShopError,
            "FORBIDDEN": ForbiddenError,
        }
        
        exception_class = error_map.get(code, AuroraPayError)
        raise exception_class(message, code=code, status_code=response.status_code)
    
    def create_order(
        self,
        amount: float,
        payment_method: str
    ) -> CreateOrderResponse:
        """
        Создать новый заказ на оплату
        
        Args:
            amount: Сумма платежа в рублях (минимум 500)
            payment_method: Метод оплаты ("card", "sbp", "kzt")
        
        Returns:
            CreateOrderResponse: Данные созданного заказа
        
        Raises:
            ValidationError: Ошибка валидации входных данных
            OrderCreationError: Ошибка создания заказа
            UnauthorizedError: Неверный API ключ
            InactiveShopError: Магазин неактивен
        
        Example:
            order = client.create_order(amount=5000, payment_method="card")
            print(f"Order ID: {order.order_id}")
            print(f"Payment Link: {order.payment_link}")
            print(f"Bank: {order.payment_details.bank_name}")
            print(f"Card/Phone: {order.payment_details.wallet_payment}")
        """
        url = f"{self.base_url}/api/order/create"
        payload = {
            "amount": amount,
            "paymentMethod": payment_method
        }
        
        try:
            response = self.session.post(url, json=payload, timeout=self.timeout)
            
            if response.status_code in (200, 201):
                data = response.json()
                return CreateOrderResponse.from_dict(data["data"])
            else:
                self._handle_error(response)
        except requests.exceptions.RequestException as e:
            raise AuroraPayError(f"Network error: {str(e)}")
    
    def get_payment_status(self, order_id: str) -> PaymentStatusResponse:
        """
        Получить статус платежа
        
        Args:
            order_id: ID заказа
        
        Returns:
            PaymentStatusResponse: Статус платежа
        
        Raises:
            OrderNotFoundError: Заказ не найден
            UnauthorizedError: Неверный API ключ
            ForbiddenError: Доступ запрещен
        
        Example:
            status = client.get_payment_status("AURO198329797418RA")
            print(f"Status: {status.status}")
            print(f"Amount: {status.amount}")
            print(f"Created: {status.created_at}")
        """
        url = f"{self.base_url}/api/payment/status/{order_id}"
        
        try:
            response = self.session.get(url, timeout=self.timeout)
            
            if response.status_code == 200:
                data = response.json()
                return PaymentStatusResponse.from_dict(data["data"])
            else:
                self._handle_error(response)
        except requests.exceptions.RequestException as e:
            raise AuroraPayError(f"Network error: {str(e)}")
    
    def close(self):
        """Закрыть сессию"""
        self.session.close()
    
    def __enter__(self):
        """Context manager support"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager support"""
        self.close()
