from fastapi import APIRouter, Depends, HTTPException, Body, Header, Request
from sqlalchemy.orm import Session
from core.db import get_db, Sale, User, Poster
from core.pay import YooKassaPayment
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
import json

class PaymentRequest(BaseModel):
    amount: float
    currency: str
    description: str
    return_url: str
    user_id: Optional[int] = Field(None)  # Делаем необязательным
    poster_id: Optional[int] = None

router = APIRouter()

# Конфигурация YooKassa
SHOP_ID = "1017909"
API_KEY = "test_udCBy7nXqGavVoj3RrzIRXN9UL02_UnF0FBBykxWH60"
payment_service = YooKassaPayment(SHOP_ID, API_KEY)

@router.post("/create-payment/")
async def create_payment(
    payment_data: dict = Body(...),  # Принимаем любой JSON
    db: Session = Depends(get_db)
):
    try:
        # Логирование для отладки
        print(f"Received payment data: {json.dumps(payment_data, ensure_ascii=False)}")
        
        # Создание платежа через YooKassa
        payment_response = payment_service.create_payment(
            amount=float(payment_data.get("amount", 0)),
            currency=payment_data.get("currency", "RUB"),
            description=payment_data.get("description", ""),
            return_url=payment_data.get("return_url", "http://localhost:3000/payments")
        )
        
        # Логирование ответа YooKassa
        print(f"YooKassa response: {json.dumps(payment_response, ensure_ascii=False)}")

        # Сохранение данных о платеже в БД
        new_sale = Sale(
            amount=float(payment_data.get("amount", 0)),
            status="pending",
            description=payment_data.get("description", ""),
            poster_id=payment_data.get("poster_id"),
            user_id=payment_data.get("user_id", 1),  # Используем 1 как значение по умолчанию
            user_email=payment_data.get("user_email", "example@example.com"),
            payment_id=payment_response["id"],
            confirmation_url=payment_response["confirmation"]["confirmation_url"]
        )
        db.add(new_sale)
        db.commit()
        db.refresh(new_sale)

        return {"confirmation_url": new_sale.confirmation_url, "payment_id": payment_response["id"]}
    except Exception as e:
        print(f"ERROR creating payment: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))

@router.get("/payment-status/{payment_id}")
async def get_payment_status(payment_id: str, db: Session = Depends(get_db)):
    try:
        print(f"Checking payment status for ID: {payment_id}")
        
        # Получение информации о платеже из БД
        sale = db.query(Sale).filter(Sale.payment_id == payment_id).first()
        
        if not sale:
            raise HTTPException(status_code=404, detail=f"Платеж с ID {payment_id} не найден")
        
        # Обновление статуса из YooKassa
        yookassa_status = payment_service.get_payment_status(payment_id)
        if yookassa_status and "status" in yookassa_status:
            # Маппинг статусов YooKassa на наши статусы
            if yookassa_status["status"] == "succeeded" or yookassa_status["paid"] == True:
                sale.status = "paid"
            elif yookassa_status["status"] == "canceled":
                sale.status = "canceled"
            elif yookassa_status["status"] == "waiting_for_capture":
                sale.status = "waiting_for_capture"
            # Сохраняем обновленный статус
            db.commit()
            print(f"Updated payment status from YooKassa: {yookassa_status['status']} -> {sale.status}")
        
        return {"payment_id": sale.payment_id, "status": sale.status}
    except Exception as e:
        print(f"ERROR checking payment status: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/notifications/")
async def process_notification(request: Request, db: Session = Depends(get_db)):
    try:
        # Получаем тело запроса
        notification_data = await request.json()
        print(f"Received notification: {json.dumps(notification_data, ensure_ascii=False)}")
        
        # Проверяем тип события
        event = notification_data.get("event")
        payment_id = notification_data.get("object", {}).get("id")
        
        if not payment_id:
            raise HTTPException(status_code=400, detail="Missing payment ID")
            
        # Находим платеж в БД
        sale = db.query(Sale).filter(Sale.payment_id == payment_id).first()
        if not sale:
            raise HTTPException(status_code=404, detail=f"Payment {payment_id} not found")
            
        # Обновляем статус платежа в зависимости от события
        if event == "payment.waiting_for_capture":
            sale.status = "waiting_for_capture"
        elif event == "payment.succeeded":
            sale.status = "paid"
        elif event == "payment.canceled":
            sale.status = "canceled"
        else:
            print(f"Unknown event: {event}")
            
        db.commit()
        return {"success": True}
    except Exception as e:
        print(f"ERROR processing notification: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/update-payment-status/")
async def manual_update_payment_status(payment_id: str, new_status: str, db: Session = Depends(get_db)):
    try:
        sale = db.query(Sale).filter(Sale.payment_id == payment_id).first()
        if not sale:
            raise HTTPException(status_code=404, detail="Платеж не найден")
        
        # Обновляем статус
        sale.status = new_status
        db.commit()
        
        return {"message": "Статус платежа обновлен", "payment_id": sale.payment_id, "status": sale.status}
    except Exception as e:
        print(f"ERROR updating payment status: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/user-tickets/{user_id}")
async def get_user_tickets(user_id: int, db: Session = Depends(get_db)):
    """Получение всех оплаченных билетов пользователя"""
    try:
        # Проверяем существование пользователя
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise HTTPException(status_code=404, detail="Пользователь не найден")
            
        # Получаем все успешно оплаченные билеты пользователя
        sales = db.query(Sale).filter(Sale.user_id == user_id, Sale.status == "paid").all()
        
        result = []
        for sale in sales:
            # Получаем информацию о мероприятии
            poster = None
            if sale.poster_id:
                poster = db.query(Poster).filter(Poster.id == sale.poster_id).first()
            
            # Формирование даты покупки
            purchase_date = sale.date if hasattr(sale, 'date') else datetime.now().isoformat()
            
            ticket_data = {
                "id": sale.id,
                "amount": sale.amount,
                "description": sale.description,
                "payment_id": sale.payment_id,
                "purchase_date": purchase_date,
                "poster": None
            }
            
            if poster:
                # Используем только те поля, которые точно есть в модели Poster
                ticket_data["poster"] = {
                    "id": poster.id,
                    "title": poster.title,
                    "date": poster.date
                    # Убрали поле img, которого нет в модели
                }
            
            result.append(ticket_data)
        
        return result
    except HTTPException as he:
        # Пробрасываем дальше HTTPException
        raise he
    except Exception as e:
        print(f"ERROR getting user tickets: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

# Для тестирования, также добавим временный эндпоинт для обновления статуса билета
@router.post("/update-ticket-status/{sale_id}")
async def update_ticket_status(sale_id: int, status: str, db: Session = Depends(get_db)):
    """Временный эндпоинт для обновления статуса билета (для тестирования)"""
    try:
        sale = db.query(Sale).filter(Sale.id == sale_id).first()
        if not sale:
            raise HTTPException(status_code=404, detail="Билет не найден")
        
        sale.status = status
        db.commit()
        
        return {"success": True, "message": f"Статус билета с ID {sale_id} обновлен на {status}"}
    except Exception as e:
        print(f"ERROR updating ticket status: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

