"""
Exchange Rate API - 환율 정보 조회 (한국수출입은행 API 연동)
"""

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime

from ..database import get_db
from ..models.exchange_rate import ExchangeRate, ExchangeRateHistory
from ..models.user import User
from .auth import get_current_admin_user
from ..services.exchange_rate_service import (
    update_exchange_rates,
    get_all_exchange_rates,
    convert_krw_to_currency,
    SUPPORTED_CURRENCIES
)

router = APIRouter(prefix="/api/exchange-rate", tags=["Exchange Rate"])


class ExchangeRateData(BaseModel):
    currency_code: str
    currency_name: str
    symbol: str
    deal_base_rate: float  # 매매기준율 (1 USD = X KRW)
    ttb_rate: float  # 전신환 받을때
    tts_rate: float  # 전신환 보낼때
    weight_percent: float  # 가중치 (%)
    adjusted_rate: float  # 가중치 적용 환율
    source_date: str
    updated_at: str


class ExchangeRatesResponse(BaseModel):
    base_currency: str
    rates: List[ExchangeRateData]
    source: str
    last_updated: str


class ExchangeRateWeightUpdate(BaseModel):
    currency_code: str
    weight_percent: float


class ConvertRequest(BaseModel):
    amount: float
    from_currency: str = "KRW"
    to_currency: str


class ConvertResponse(BaseModel):
    original_amount: float
    from_currency: str
    converted_amount: float
    to_currency: str
    rate_used: float


@router.get("", response_model=ExchangeRatesResponse)
async def get_exchange_rates(db: Session = Depends(get_db)):
    """환율 정보 조회"""

    rates = get_all_exchange_rates(db)

    # DB에 데이터가 없으면 업데이트 시도
    if not rates:
        await update_exchange_rates(db)
        rates = get_all_exchange_rates(db)

    rate_list = []
    for rate in rates:
        symbol = SUPPORTED_CURRENCIES.get(rate.currency_code, {}).get("symbol", "")
        rate_list.append(ExchangeRateData(
            currency_code=rate.currency_code,
            currency_name=rate.currency_name,
            symbol=symbol,
            deal_base_rate=rate.deal_base_rate,
            ttb_rate=rate.ttb_rate or rate.deal_base_rate,
            tts_rate=rate.tts_rate or rate.deal_base_rate,
            weight_percent=rate.weight_percent or 0.0,
            adjusted_rate=rate.adjusted_rate or rate.deal_base_rate,
            source_date=rate.source_date or "",
            updated_at=rate.updated_at.isoformat() if rate.updated_at else ""
        ))

    last_updated = ""
    if rates:
        latest = max(rates, key=lambda r: r.updated_at if r.updated_at else datetime.min)
        last_updated = latest.updated_at.isoformat() if latest.updated_at else ""

    return ExchangeRatesResponse(
        base_currency="KRW",
        rates=rate_list,
        source="koreaexim",
        last_updated=last_updated
    )


@router.get("/currency/{currency_code}")
async def get_single_rate(currency_code: str, db: Session = Depends(get_db)):
    """특정 통화 환율 조회"""
    rate = db.query(ExchangeRate).filter(
        ExchangeRate.currency_code == currency_code.upper(),
        ExchangeRate.is_active == True
    ).first()

    if not rate:
        raise HTTPException(status_code=404, detail=f"Currency {currency_code} not found")

    symbol = SUPPORTED_CURRENCIES.get(rate.currency_code, {}).get("symbol", "")

    return {
        "currency_code": rate.currency_code,
        "currency_name": rate.currency_name,
        "symbol": symbol,
        "deal_base_rate": rate.deal_base_rate,
        "adjusted_rate": rate.adjusted_rate,
        "weight_percent": rate.weight_percent,
        "source_date": rate.source_date,
        "updated_at": rate.updated_at.isoformat() if rate.updated_at else None
    }


@router.post("/convert", response_model=ConvertResponse)
async def convert_currency(
    request: ConvertRequest,
    db: Session = Depends(get_db)
):
    """통화 변환"""
    if request.from_currency.upper() != "KRW":
        raise HTTPException(status_code=400, detail="Currently only KRW conversion is supported")

    converted = convert_krw_to_currency(db, request.amount, request.to_currency.upper())

    if converted is None:
        raise HTTPException(status_code=404, detail=f"Currency {request.to_currency} not found")

    rate = db.query(ExchangeRate).filter(
        ExchangeRate.currency_code == request.to_currency.upper()
    ).first()

    return ConvertResponse(
        original_amount=request.amount,
        from_currency=request.from_currency.upper(),
        converted_amount=round(converted, 2),
        to_currency=request.to_currency.upper(),
        rate_used=rate.adjusted_rate if rate else 0
    )


@router.get("/weights")
async def get_exchange_rate_weights(db: Session = Depends(get_db)):
    """환율 가중치 설정 조회"""
    rates = get_all_exchange_rates(db)

    return {
        rate.currency_code.lower(): rate.weight_percent or 0.0
        for rate in rates
    }


@router.put("/weights/{currency_code}")
async def update_exchange_rate_weight(
    currency_code: str,
    weight_percent: float,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """환율 가중치 수정 (관리자 전용)"""
    rate = db.query(ExchangeRate).filter(
        ExchangeRate.currency_code == currency_code.upper()
    ).first()

    if not rate:
        raise HTTPException(status_code=404, detail=f"Currency {currency_code} not found")

    rate.weight_percent = weight_percent
    rate.adjusted_rate = rate.deal_base_rate * (1 + weight_percent / 100)

    db.commit()

    return {
        "message": "Weight updated successfully",
        "currency_code": rate.currency_code,
        "weight_percent": rate.weight_percent,
        "adjusted_rate": rate.adjusted_rate
    }


@router.post("/refresh")
async def refresh_exchange_rates(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """환율 강제 갱신 (관리자 전용)"""
    result = await update_exchange_rates(db, force=True)

    return result


@router.get("/history/{currency_code}")
async def get_exchange_rate_history(
    currency_code: str,
    limit: int = 30,
    db: Session = Depends(get_db)
):
    """환율 변동 이력 조회"""
    history = db.query(ExchangeRateHistory).filter(
        ExchangeRateHistory.currency_code == currency_code.upper()
    ).order_by(ExchangeRateHistory.created_at.desc()).limit(limit).all()

    return [
        {
            "currency_code": h.currency_code,
            "deal_base_rate": h.deal_base_rate,
            "source_date": h.source_date,
            "created_at": h.created_at.isoformat() if h.created_at else None
        }
        for h in history
    ]


# 프론트엔드용 간단 API
@router.get("/simple")
async def get_simple_rates(db: Session = Depends(get_db)):
    """프론트엔드용 간단 환율 정보"""
    rates = get_all_exchange_rates(db)

    # DB에 데이터가 없으면 업데이트 시도
    if not rates:
        await update_exchange_rates(db)
        rates = get_all_exchange_rates(db)

    result = {}
    for rate in rates:
        result[rate.currency_code] = {
            "rate": rate.adjusted_rate,  # KRW per 1 unit (e.g., 1 USD = 1450 KRW)
            "symbol": SUPPORTED_CURRENCIES.get(rate.currency_code, {}).get("symbol", ""),
            "name": rate.currency_name
        }

    return result
