import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { getStockIndices, getStockNews, getFearAndGreed, getVix, getTreasury10Y, getWTI, getBrent } from '../../api';
import Loading from '../../components/Loading';
import FearGreedGauge from '../../components/FearGreedGauge';
import { useIsMobile } from '../../hooks/useIsMobile';
import PullToRefresh from '../../components/PullToRefresh';
import FAB from '../../components/FAB';
import './Stock.css';

const formatDate = (value) => {
    if (!value) return '-';
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return value;
    return date.toLocaleString('sv-SE');
};

const normalizeIndices = (data) => {
    if (!data) return [];

    if (Array.isArray(data)) {
        return data.map((item) => ({
            name: item?.name ?? item?.key ?? '-',
            value: item?.value ?? '-',
            change: item?.change_value ?? item?.change ?? '',
            percent: item?.change_percent ?? item?.percent ?? '',
            direction: item?.direction ?? '',
        }));
    }

    if (Array.isArray(data?.indices)) {
        return data.indices.map((item) => ({
            name: item?.name ?? item?.key ?? '-',
            value: item?.value ?? '-',
            change: item?.change_value ?? item?.change ?? '',
            percent: item?.change_percent ?? item?.percent ?? '',
            direction: item?.direction ?? '',
        }));
    }

    if (typeof data === 'object') {
        return Object.entries(data)
            .filter(([, value]) => value && typeof value === 'object')
            .map(([name, value]) => ({
                name,
                value: value?.value ?? '-',
                change: value?.change ?? '',
                percent: value?.percent ?? '',
                direction: value?.direction ?? '',
            }));
    }

    return [];
};

const getDirection = (change, percent, direction) => {
    // 숫자 부호로 방향 추출 (percent → change 순서로 시도)
    const fromStr = (s) => {
        if (s === undefined || s === null || s === '') return null;
        const str = String(s).trim();
        if (str.startsWith('-')) return 'down';
        if (str.startsWith('+')) return 'up';
        const numeric = Number(str.replace(/[^0-9.-]/g, ''));
        if (Number.isFinite(numeric) && numeric !== 0) {
            return numeric > 0 ? 'up' : 'down';
        }
        return null;
    };
    // percent 필드가 부호를 가장 신뢰성 있게 포함하는 경우가 많음
    const byPercent = fromStr(percent);
    if (byPercent) return byPercent;
    const byChange = fromStr(change);
    if (byChange) return byChange;
    // 숫자로 판별 불가 시 direction 필드 fallback
    if (direction) {
        const d = String(direction).toLowerCase();
        if (d === 'red' || d === 'up' || d === 'rise' || d === 'positive') return 'up';
        if (d === 'blue' || d === 'down' || d === 'fall' || d === 'negative') return 'down';
    }
    return '';
};

const VIX_LEVELS = [
    {
        range: '0 – 12', label: '극히 낮음', color: '#22c55e',
        desc: '시장이 극도로 안정적. 오히려 투자자 안일함의 신호일 수 있어, 갑작스러운 조정에 대비가 필요합니다.',
    },
    {
        range: '12 – 20', label: '정상', color: '#84cc16',
        desc: '시장이 안정적인 상태. 보통 상승장에서 나타나며, 건강한 변동성 수준입니다.',
    },
    {
        range: '20 – 30', label: '주의', color: '#eab308',
        desc: '불확실성이 높아지는 구간. 주가와 반대로 움직이며, 단기 바닥 신호로 해석되기도 합니다.',
    },
    {
        range: '30 – 40', label: '높음', color: '#f97316',
        desc: '극도의 공포가 퍼진 상태. 급격한 매도세가 나타나지만, 역사적으로 역발상 매수 기회가 되기도 합니다.',
    },
    {
        range: '40+', label: '극단', color: '#ef4444',
        desc: '패닉 수준의 공포. 2008 금융위기·2020 코로나 때 발생. VIX가 꺾이기 시작하면 심리적 진정의 시작입니다.',
    },
];

const getVixLevel = (score) => {
    if (score < 12) return VIX_LEVELS[0];
    if (score < 20) return VIX_LEVELS[1];
    if (score < 30) return VIX_LEVELS[2];
    if (score < 40) return VIX_LEVELS[3];
    return VIX_LEVELS[4];
};

const Stock = () => {
    const isMobile = useIsMobile();
    const [newsDomestic, setNewsDomestic] = useState([]);
    const [newsOverseas, setNewsOverseas] = useState([]);
    const [newsCategory, setNewsCategory] = useState('domestic');
    const [limit, setLimit] = useState(20);
    const [loading, setLoading] = useState(false);
    const [newsError, setNewsError] = useState('');
    const [indicesError, setIndicesError] = useState('');
    const [indices, setIndices] = useState([]);
    const [indicesLoading, setIndicesLoading] = useState(false);
    const [autoRefreshMs] = useState(180000);

    const [fgData, setFgData] = useState(null);
    const [vixData, setVixData] = useState(null);
    const [macroData, setMacroData] = useState({ treasury: null, wti: null, brent: null });

    const combinedNews = useMemo(
        () => [...newsDomestic, ...newsOverseas],
        [newsDomestic, newsOverseas]
    );

    const loadNews = async () => {
        setLoading(true);
        setNewsError('');
        try {
            const [domestic, overseas] = await Promise.all([
                getStockNews(limit, 'domestic'),
                getStockNews(limit, 'overseas'),
            ]);
            setNewsDomestic(Array.isArray(domestic) ? domestic : []);
            setNewsOverseas(Array.isArray(overseas) ? overseas : []);
        } catch (err) {
            setNewsError(err?.message ?? String(err));
        } finally {
            setLoading(false);
        }
    };

    const handleRefresh = useCallback(async () => {
        await loadNews();
    }, []); // eslint-disable-line react-hooks/exhaustive-deps

    const loadIndices = async () => {
        setIndicesLoading(true);
        setIndicesError('');
        try {
            const data = await getStockIndices();
            setIndices(normalizeIndices(data));
        } catch (err) {
            setIndicesError(err?.message ?? String(err));
        } finally {
            setIndicesLoading(false);
        }
    };

    useEffect(() => {
        loadNews();
    }, [limit]);

    useEffect(() => {
        loadIndices();
        const timer = window.setInterval(loadIndices, autoRefreshMs);
        return () => window.clearInterval(timer);
    }, [autoRefreshMs]);

    useEffect(() => {
        const loadSentiment = () => {
            getFearAndGreed()
                .then((data) => {
                    const fg = data?.fear_and_greed ?? data;
                    const score = typeof fg?.score === 'number' ? fg.score : parseFloat(fg?.score);
                    if (!isNaN(score)) {
                        setFgData({ score, timestamp: fg?.timestamp ?? null });
                    }
                })
                .catch(() => { });
            getVix().then(setVixData).catch(() => { });
            Promise.allSettled([getTreasury10Y(), getWTI(), getBrent()])
                .then(([t, w, b]) => {
                    setMacroData({
                        treasury: t.status === 'fulfilled' ? t.value : null,
                        wti: w.status === 'fulfilled' ? w.value : null,
                        brent: b.status === 'fulfilled' ? b.value : null,
                    });
                });
        };
        loadSentiment();
        const timer = window.setInterval(loadSentiment, 600000); // 10분마다 갱신
        return () => window.clearInterval(timer);
    }, []);

    const indexOrder = [
        'KOSPI',
        'KOSDAQ',
        'KOSPI200',
        '다우산업',
        '나스닥',
        'S&P500',
        '원달러 환율',
    ];
    const sortedIndices = [...indices].sort((a, b) => {
        const aIndex = indexOrder.indexOf(a.name);
        const bIndex = indexOrder.indexOf(b.name);
        if (aIndex !== -1 || bIndex !== -1) {
            return (aIndex === -1 ? 999 : aIndex) - (bIndex === -1 ? 999 : bIndex);
        }
        return a.name.localeCompare(b.name);
    });
    const highlighted = new Set(['KOSPI', 'KOSDAQ', '원달러 환율']);
    const activeNews =
        newsCategory === 'domestic' ? newsDomestic : newsOverseas;

    return (
        <PullToRefresh onRefresh={handleRefresh}>
        <div className="stock">
            <header className="stock-header">
                <div>
                    <p className="stock-kicker">마켓 랩</p>
                    <h1>주식 랩</h1>
                    <p className="stock-sub">
                        최신 시장 뉴스와 주요 지수 흐름을 한눈에 확인하세요.
                    </p>
                    <div className="stock-actions">
                        <button
                            className="button primary"
                            onClick={loadNews}
                            disabled={loading}
                        >
                            뉴스 새로고침
                        </button>
                        <Link className="button ghost" to="/stock/trade">
                            거래 데스크
                        </Link>
                    </div>
                </div>
                <div className="stock-card">
                    <p className="stock-card__title">다음 업데이트 아이디어</p>
                    <ul className="stock-ideas">
                        <li>관심 종목 실적 캘린더/일정 보기</li>
                        <li>뉴스 감성 요약 및 키워드 트렌드</li>
                        <li>보유 종목 알림(수익률/목표가)</li>
                    </ul>
                </div>
            </header>

            <section className="stock-panel stock-panel--wide">
                <div className="stock-panel__head">
                    <div>
                        <p className="stock-panel__eyebrow">스냅샷</p>
                        <h3>주요 지수</h3>
                        <p className="stock-panel__sub">
                            주요 지수 값과 등락을 함께 확인합니다.
                        </p>
                    </div>
                    <div className="stock-panel__actions">
                        {indicesLoading ? (
                            <Loading type="spinner" message="" />
                        ) : null}
                        <button
                            className="button ghost small"
                            onClick={loadIndices}
                            disabled={indicesLoading}
                        >
                            새로고침
                        </button>
                    </div>
                </div>
                <div className="stock-snapshot">
                    {indicesError ? (
                        <p className="stock-empty">{indicesError}</p>
                    ) : sortedIndices.length === 0 ? (
                        <p className="stock-empty">
                            지수 데이터가 없습니다.
                        </p>
                    ) : (
                        sortedIndices.map((item) => {
                            const direction = getDirection(
                                item.change,
                                item.percent,
                                item.direction
                            );
                            const changeText = [item.change, item.percent]
                                .filter(Boolean)
                                .join(' ');
                            return (
                                <div
                                    key={item.name}
                                    className={`stock-snapshot__card ${highlighted.has(item.name)
                                        ? 'is-highlight'
                                        : ''
                                        }`}
                                >
                                    <p>{item.name}</p>
                                    <strong>{item.value ?? '--'}</strong>
                                    <span
                                        className={`stock-snapshot__change ${direction === 'up'
                                            ? 'is-up'
                                            : direction === 'down'
                                                ? 'is-down'
                                                : ''
                                            }`}
                                    >
                                        {changeText || '--'}
                                    </span>
                                </div>
                            );
                        })
                    )}
                </div>
            </section>

            {/* 시장 심리 지표 행 */}
            <section className="stock-filter-row">
                <div className="stock-panel stock-panel--compact">
                    <div className="stock-panel__head">
                        <div>
                            <p className="stock-panel__eyebrow">심리 지표</p>
                            <h3>Fear & Greed</h3>
                            <p className="stock-panel__sub">시장 탐욕·공포 지수 (0–100)</p>
                        </div>
                    </div>
                    {fgData ? (
                        <FearGreedGauge
                            score={Math.round(fgData.score)}
                            date={fgData.timestamp ? new Date(fgData.timestamp).toLocaleDateString('ko-KR') : undefined}
                            showLevels
                        />
                    ) : (
                        <p className="stock-empty" style={{ fontSize: 13 }}>데이터 없음</p>
                    )}
                </div>
                <div className="stock-panel stock-panel--compact">
                    <div className="stock-panel__head">
                        <div>
                            <p className="stock-panel__eyebrow">변동성 지수</p>
                            <h3>VIX</h3>
                            <p className="stock-panel__sub">CBOE 공포 지수</p>
                        </div>
                    </div>
                    {vixData ? (
                        <div className="stock-vix">
                            <div className="stock-vix__top">
                                <div className="stock-vix__score" style={{ color: getVixLevel(vixData.value ?? 0).color }}>
                                    {vixData.value ?? '--'}
                                </div>
                                <div>
                                    <p className="stock-vix__label" style={{ color: getVixLevel(vixData.value ?? 0).color }}>
                                        {getVixLevel(vixData.value ?? 0).label}
                                    </p>
                                    {vixData.change != null && (
                                        <p className={`stock-vix__change ${vixData.change >= 0 ? 'is-up' : 'is-down'}`}>
                                            {vixData.change >= 0 ? '+' : ''}{vixData.change}
                                            {vixData.changePercent != null && ` (${vixData.changePercent >= 0 ? '+' : ''}${vixData.changePercent}%)`}
                                        </p>
                                    )}
                                </div>
                            </div>
                            <div className="stock-vix__levels">
                                {VIX_LEVELS.map((level) => (
                                    <div
                                        key={level.range}
                                        className={`stock-vix__level ${level.label === getVixLevel(vixData.value ?? 0).label ? 'is-current' : ''}`}
                                    >
                                        <div className="stock-vix__level-head">
                                            <span className="stock-vix__level-dot" style={{ background: level.color }} />
                                            <span className="stock-vix__level-label" style={{ color: level.color }}>{level.label}</span>
                                            <span className="stock-vix__level-range">{level.range}</span>
                                        </div>
                                        <p className="stock-vix__level-desc">{level.desc}</p>
                                    </div>
                                ))}
                            </div>
                        </div>
                    ) : (
                        <p className="stock-empty" style={{ fontSize: 13 }}>데이터 없음</p>
                    )}
                </div>
            </section>

            {/* 매크로 지표 섹션 */}
            <section className="stock-panel stock-panel--wide">
                <div className="stock-panel__head">
                    <div>
                        <p className="stock-panel__eyebrow">글로벌 매크로</p>
                        <h3>매크로 지표</h3>
                        <p className="stock-panel__sub">금리·원자재 등 주요 거시경제 지표를 확인합니다.</p>
                    </div>
                </div>
                <div className="stock-macro-grid">
                    <div className="stock-macro-card">
                        <p className="stock-macro-card__title">미국 10년물 국채 금리</p>
                        <div className="stock-macro-card__value">
                            {macroData.treasury ? `${macroData.treasury.value}%` : '--'}
                        </div>
                        {macroData.treasury?.change != null && (
                            <p className={`stock-macro-card__change ${macroData.treasury.change >= 0 ? 'is-up' : 'is-down'}`}>
                                {macroData.treasury.change >= 0 ? '+' : ''}{macroData.treasury.change}
                                {macroData.treasury.changePercent != null && ` (${macroData.treasury.changePercent >= 0 ? '+' : ''}${macroData.treasury.changePercent}%)`}
                            </p>
                        )}
                        <p className="stock-macro-card__desc">금리 상승 시 주식 밸류에이션 압박. 4% 이상 지속은 주식 하락 압력 신호. 단기 급등은 인플레이션 우려를 반영합니다.</p>
                    </div>
                    <div className="stock-macro-card">
                        <p className="stock-macro-card__title">WTI 유가</p>
                        <div className="stock-macro-card__value">
                            {macroData.wti ? `$${macroData.wti.value}` : '--'}
                        </div>
                        {macroData.wti?.change != null && (
                            <p className={`stock-macro-card__change ${macroData.wti.change >= 0 ? 'is-up' : 'is-down'}`}>
                                {macroData.wti.change >= 0 ? '+' : ''}{macroData.wti.change}
                                {macroData.wti.changePercent != null && ` (${macroData.wti.changePercent >= 0 ? '+' : ''}${macroData.wti.changePercent}%)`}
                            </p>
                        )}
                        <p className="stock-macro-card__desc">에너지 인플레이션 지표. $80 이상 지속 시 물가 상승 우려 확대. 급락은 경기침체 가능성을 반영하기도 합니다.</p>
                    </div>
                    <div className="stock-macro-card">
                        <p className="stock-macro-card__title">Brent 유가</p>
                        <div className="stock-macro-card__value">
                            {macroData.brent ? `$${macroData.brent.value}` : '--'}
                        </div>
                        {macroData.brent?.change != null && (
                            <p className={`stock-macro-card__change ${macroData.brent.change >= 0 ? 'is-up' : 'is-down'}`}>
                                {macroData.brent.change >= 0 ? '+' : ''}{macroData.brent.change}
                                {macroData.brent.changePercent != null && ` (${macroData.brent.changePercent >= 0 ? '+' : ''}${macroData.brent.changePercent}%)`}
                            </p>
                        )}
                        <p className="stock-macro-card__desc">국제 기준 유가. WTI와 함께 에너지 시장 방향을 파악하는 데 활용. 지정학 리스크 시 WTI 대비 프리미엄 형성.</p>
                    </div>
                </div>
            </section>

            {/* 시장 건강 지표 (Placeholder) */}
            <section className="stock-panel stock-panel--wide">
                <div className="stock-panel__head">
                    <div>
                        <p className="stock-panel__eyebrow">시장 건강</p>
                        <h3>시장 건강 지표</h3>
                        <p className="stock-panel__sub">백엔드 API 연동 후 실시간 데이터를 표시합니다.</p>
                    </div>
                </div>
                <div className="stock-health-grid">
                    <div className="stock-placeholder-card">
                        <p className="stock-placeholder-card__title">ADR (등락주선 비율)</p>
                        <div className="stock-placeholder-card__status">🔧 데이터 준비 중</div>
                        <p className="stock-placeholder-card__desc">일정 기간 상승종목 ÷ (상승+하락) 종목 비율. 0.5 이상 = 폭넓은 상승장. 0.3 이하 = 일부 대형주만 오르는 약세 신호.</p>
                        <code className="stock-placeholder-card__api">GET /api/stock/adr</code>
                    </div>
                    <div className="stock-placeholder-card">
                        <p className="stock-placeholder-card__title">고객예탁금 / 신용융자</p>
                        <div className="stock-placeholder-card__status">🔧 데이터 준비 중</div>
                        <p className="stock-placeholder-card__desc">고객예탁금 증가 = 투자 대기자금 유입 = 강세. 신용융자 급증 = 과열 경고. 예탁금 감소 + 신용 급증 = 위험 구간.</p>
                        <code className="stock-placeholder-card__api">GET /api/stock/deposit</code>
                    </div>
                </div>
            </section>

            <section className="stock-panel stock-panel--wide">
                <div className="stock-panel__head">
                    <div>
                        <p className="stock-panel__eyebrow">헤드라인</p>
                        <h3>시장 뉴스</h3>
                        <p className="stock-panel__sub">
                            Stock Lab API에서 최신 뉴스를 불러옵니다.
                        </p>
                    </div>
                    <div className="stock-panel__actions">
                        {loading && <span className="stock-chip">Updating...</span>}
                        <span className="stock-chip">
                            국내 {newsDomestic.length} / 해외{' '}
                            {newsOverseas.length}
                        </span>
                    </div>
                </div>

                {loading && combinedNews.length === 0 ? (
                    <Loading type="skeleton" />
                ) : newsError ? (
                    <p className="stock-empty">{newsError}</p>
                ) : combinedNews.length === 0 ? (
                    <p className="stock-empty">뉴스가 없습니다.</p>
                ) : (
                    <>
                        <div className="stock-news-toolbar">
                            <div className="stock-tabs">
                                <button
                                    type="button"
                                    className={`stock-tab ${newsCategory === 'domestic' ? 'is-active' : ''}`}
                                    onClick={() => setNewsCategory('domestic')}
                                >
                                    국내 <span className="stock-tab-count">{newsDomestic.length}</span>
                                </button>
                                <button
                                    type="button"
                                    className={`stock-tab ${newsCategory === 'overseas' ? 'is-active' : ''}`}
                                    onClick={() => setNewsCategory('overseas')}
                                >
                                    해외 <span className="stock-tab-count">{newsOverseas.length}</span>
                                </button>
                            </div>
                            <select
                                className="stock-news-limit"
                                value={limit}
                                onChange={(e) => setLimit(Number(e.target.value))}
                            >
                                {[10, 20, 30, 40].map((v) => (
                                    <option key={v} value={v}>{v}개</option>
                                ))}
                            </select>
                        </div>
                        {activeNews.length === 0 ? (
                            <p className="stock-empty">
                                해당 카테고리 뉴스가 없습니다.
                            </p>
                        ) : (
                            <div className="stock-news-grid">
                                {activeNews.map((item) => (
                                    <article
                                        key={item.id ?? item.link}
                                        className="stock-news-card"
                                    >
                                        <div className="stock-news-card__head">
                                            <span className="stock-news-card__date">
                                                {formatDate(item.published_at)}
                                            </span>
                                            {item.sentiment ? (
                                                <span className="stock-chip">
                                                    {item.sentiment}
                                                </span>
                                            ) : null}
                                        </div>
                                        <p className="stock-news-card__title">
                                            {item.title}
                                        </p>
                                        {item.summary && (
                                            <p className="stock-news-card__summary">
                                                {item.summary}
                                            </p>
                                        )}
                                        {item.link && (
                                            <a
                                                href={item.link}
                                                target="_blank"
                                                rel="noreferrer"
                                                className="stock-news-card__link"
                                            >
                                                원문 보기 →
                                            </a>
                                        )}
                                    </article>
                                ))}
                            </div>
                        )}
                    </>
                )}
            </section>
        </div>
        <FAB onClick={loadNews} label="뉴스 새로고침" icon={
            <svg className="fab__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <polyline points="23 4 23 10 17 10"/>
                <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/>
            </svg>
        } />
        </PullToRefresh>
    );
};

export default Stock;
