import pandas as pd
import requests
from typing import Optional

# Primary market data source switched to Yahoo Finance (yfinance)
# because Stooq historical CSV endpoint started returning empty responses.
import yfinance as yf


def get_usd_krw() -> Optional[float]:
    try:
        url = "https://open.er-api.com/v6/latest/USD"
        response = requests.get(url, timeout=10)
        data = response.json()
        if data.get("result") == "success":
            rate = data.get("rates", {}).get("KRW")
            return float(rate) if rate is not None else None
    except Exception:
        pass
    return None


def fetch_spx_history() -> pd.DataFrame:
    """Fetch daily OHLCV for S&P 500.

    Returns a dataframe with a Date index and a 'Close' column.
    """
    # Need >= 200 trading days to compute MA200. Use 2y to be safe.
    df = yf.download("^GSPC", period="2y", interval="1d", progress=False, auto_adjust=False)
    if df is None or df.empty:
        raise RuntimeError("Failed to fetch ^GSPC history from Yahoo Finance")

    # yfinance returns multiindex columns sometimes
    if isinstance(df.columns, pd.MultiIndex):
        # ('Close','^GSPC') 형태
        if ("Close", "^GSPC") in df.columns:
            df = df[("Close", "^GSPC")].to_frame(name="Close")
        else:
            df.columns = [c[0] for c in df.columns]

    if "Close" not in df.columns:
        raise RuntimeError("Yahoo Finance response missing Close column")

    df = df.reset_index().rename(columns={"index": "Date"})
    if "Date" not in df.columns:
        # yfinance typically provides 'Date' index name
        df = df.rename(columns={df.columns[0]: "Date"})

    df = df[["Date", "Close"]].dropna().copy()
    df["Date"] = pd.to_datetime(df["Date"]).dt.date.astype(str)
    return df


def check_snp500() -> str:
    try:
        df = fetch_spx_history()

        if len(df) < 205:
            return "❌ 데이터 부족: 200일치 이상의 데이터가 필요합니다."

        # Calculate MAs
        df["MA5"] = df["Close"].rolling(window=5).mean()
        df["MA20"] = df["Close"].rolling(window=20).mean()
        df["MA50"] = df["Close"].rolling(window=50).mean()
        df["MA200"] = df["Close"].rolling(window=200).mean()

        last_row = df.iloc[-1]
        prev_row = df.iloc[-2]

        last_date = last_row["Date"]
        prev_date = prev_row["Date"]
        current_price = float(last_row["Close"])
        prev_close = float(prev_row["Close"])

        day_change = current_price - prev_close
        day_change_pct = (day_change / prev_close) * 100 if prev_close else float("nan")
        day_change_str = (
            f"\n전일({prev_date}) 종가 대비: {day_change_pct:+.2f}% ({day_change:+,.2f})"
            if prev_close
            else ""
        )

        now_ma5 = float(last_row["MA5"])
        now_ma20 = float(last_row["MA20"])
        now_ma50 = float(last_row["MA50"])
        now_ma200 = float(last_row["MA200"])
        prev_ma50 = float(prev_row["MA50"])
        prev_ma200 = float(prev_row["MA200"])

        usd_krw = get_usd_krw()
        fx_str = f"\n💵 **원/달러 환율**: {usd_krw:,.2f}원" if usd_krw else ""

        # Cross detection + status
        prev_state = "골든크로스 상태" if prev_ma50 > prev_ma200 else "데드크로스 상태"
        now_state = "골든크로스 상태" if now_ma50 > now_ma200 else "데드크로스 상태"

        if prev_ma50 <= prev_ma200 and now_ma50 > now_ma200:
            headline = f"🚀 **SNP 500 골든크로스 발생!** ({last_date})"
            cross_note = "오늘 신규 크로스 여부: **오늘 신규 골든크로스 발생(50일선이 200일선을 상향 돌파)**"
        elif prev_ma50 >= prev_ma200 and now_ma50 < now_ma200:
            headline = f"⚠️ **SNP 500 데드크로스 발생!** ({last_date})"
            cross_note = "오늘 신규 크로스 여부: **오늘 신규 데드크로스 발생(50일선이 200일선 아래로 하향 돌파)**"
        else:
            headline = f"📊 **SNP 500 현황 보고** ({last_date})"
            cross_note = "오늘 신규 크로스 여부: 신규 골든/데드크로스 발생 없음"

        trend = "상승 추세 유지" if now_ma50 > now_ma200 else "하락 추세 유지"

        msg = (
            f"{headline}\n"
            f"현재 {trend} 중입니다.\n"
            f"- 5일선: {now_ma5:,.2f}\n"
            f"- 20일선: {now_ma20:,.2f}\n"
            f"- 50일선: {now_ma50:,.2f}\n"
            f"- 200일선: {now_ma200:,.2f}\n"
            f"- 현재가: {current_price:,.2f}\n"
            f"\n장기 추세 상태: **{now_state} (50일선 {'>' if now_ma50 > now_ma200 else '<='} 200일선)**\n"
            f"전일 상태: **{prev_state}**\n"
            f"{cross_note}"
        )

        return msg + day_change_str + fx_str

    except Exception as e:
        return f"❌ 스크립트 실행 중 오류 발생: {str(e)}"


if __name__ == "__main__":
    print(check_snp500())
