import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react';
import { Link } from 'react-router-dom';
import {
    createTradeOrder,
    getTradeBalance,
    getPortfolio,
    addPortfolio,
    updatePortfolio,
    deletePortfolio,
} from '../../api';
import Loading from '../../components/Loading';
import './Stock.css';

/* ── helpers ─────────────────────────────────────────────────────── */

const formatNumber = (value) => {
    if (value === null || value === undefined || value === '') return '-';
    const numeric = Number(value);
    if (Number.isNaN(numeric)) return value;
    return new Intl.NumberFormat('ko-KR').format(numeric);
};

const formatPercent = (value) => {
    if (value === null || value === undefined || value === '') return '-';
    if (typeof value === 'string' && value.includes('%')) return value;
    const numeric = Number(value);
    if (Number.isNaN(numeric)) return value;
    return `${numeric >= 0 ? '+' : ''}${numeric.toFixed(2)}%`;
};

const pickFirst = (...values) =>
    values.find((value) => value !== undefined && value !== null && value !== '');

const getQty = (item) =>
    pickFirst(item?.qty, item?.quantity, item?.holding, item?.hold_qty);

const getBuyPrice = (item) =>
    pickFirst(
        item?.buy_price,
        item?.avg_price,
        item?.avg,
        item?.purchase_price,
        item?.buyPrice,
        item?.price
    );

const getCurrentPrice = (item) =>
    pickFirst(
        item?.current_price,
        item?.current,
        item?.cur_price,
        item?.now_price,
        item?.market_price
    );

const getProfitRate = (item) =>
    pickFirst(
        item?.profit_rate,
        item?.profitRate,
        item?.profit_pct,
        item?.profitPercent,
        item?.pnl_rate,
        item?.return_rate,
        item?.yield
    );

const getProfitLoss = (item) =>
    pickFirst(item?.profit_loss, item?.pnl, item?.profitLoss);

const toNumeric = (value) => {
    if (value === null || value === undefined || value === '') return null;
    const numeric = Number(String(value).replace(/[^0-9.-]/g, ''));
    return Number.isNaN(numeric) ? null : numeric;
};

const profitColorClass = (numericValue) => {
    if (numericValue > 0) return 'is-up';
    if (numericValue < 0) return 'is-down';
    if (numericValue === 0) return 'is-flat';
    return '';
};

/* ── empty portfolio form ────────────────────────────────────────── */

const emptyPortfolioForm = {
    broker: '',
    ticker: '',
    name: '',
    quantity: '',
    avg_price: '',
};

/* ── component ───────────────────────────────────────────────────── */

const StockTrade = () => {
    /* Balance state */
    const [balance, setBalance] = useState(null);
    const [balanceLoading, setBalanceLoading] = useState(false);
    const [balanceError, setBalanceError] = useState('');

    /* Portfolio state */
    const [portfolio, setPortfolio] = useState(null);
    const [portfolioLoading, setPortfolioLoading] = useState(false);
    const [portfolioError, setPortfolioError] = useState('');

    /* Portfolio add form */
    const [addForm, setAddForm] = useState({ ...emptyPortfolioForm });
    const [addFormOpen, setAddFormOpen] = useState(false);
    const [addLoading, setAddLoading] = useState(false);
    const [addError, setAddError] = useState('');

    /* Portfolio edit */
    const [editingId, setEditingId] = useState(null);
    const [editForm, setEditForm] = useState({});
    const [editLoading, setEditLoading] = useState(false);
    const editOrigRef = useRef({});

    /* Portfolio delete */
    const [deleteConfirmId, setDeleteConfirmId] = useState(null);

    /* Manual order state */
    const [manualForm, setManualForm] = useState({
        code: '',
        qty: 1,
        price: 0,
        type: 'buy',
    });
    const [manualLoading, setManualLoading] = useState(false);
    const [manualError, setManualError] = useState('');
    const [manualResult, setManualResult] = useState(null);
    const [kisModal, setKisModal] = useState('');

    /* ── loaders ─────────────────────────────────────────────────── */

    const loadBalance = useCallback(async () => {
        setBalanceLoading(true);
        setBalanceError('');
        try {
            const data = await getTradeBalance();
            setBalance(data);
        } catch (err) {
            setBalanceError(err?.message ?? String(err));
        } finally {
            setBalanceLoading(false);
        }
    }, []);

    const loadPortfolio = useCallback(async () => {
        setPortfolioLoading(true);
        setPortfolioError('');
        try {
            const data = await getPortfolio();
            setPortfolio(data);
        } catch (err) {
            setPortfolioError(err?.message ?? String(err));
        } finally {
            setPortfolioLoading(false);
        }
    }, []);

    useEffect(() => {
        loadBalance();
        loadPortfolio();
    }, [loadBalance, loadPortfolio]);

    /* Auto-refresh portfolio every 3 min */
    useEffect(() => {
        const timer = window.setInterval(loadPortfolio, 180000);
        return () => window.clearInterval(timer);
    }, [loadPortfolio]);

    /* ── portfolio actions ───────────────────────────────────────── */

    const handleAddSubmit = async (e) => {
        e.preventDefault();
        setAddLoading(true);
        setAddError('');
        try {
            await addPortfolio({
                broker: addForm.broker.trim(),
                ticker: addForm.ticker.trim(),
                name: addForm.name.trim(),
                quantity: Number(addForm.quantity),
                avg_price: Number(addForm.avg_price),
            });
            setAddForm({ ...emptyPortfolioForm });
            setAddFormOpen(false);
            await loadPortfolio();
        } catch (err) {
            setAddError(err?.message ?? String(err));
        } finally {
            setAddLoading(false);
        }
    };

    const handleEditStart = (item) => {
        setEditingId(item.id);
        setEditForm({
            quantity: item.quantity,
            avg_price: item.avg_price,
            broker: item.broker,
            name: item.name,
        });
        /* 원본 값을 기억해서 diff 비교용 */
        editOrigRef.current = {
            quantity: item.quantity,
            avg_price: item.avg_price,
            broker: item.broker,
            name: item.name,
        };
    };

    const handleEditSave = async (id) => {
        setEditLoading(true);
        try {
            /* 변경된 필드만 추출하여 부분 수정 */
            const orig = editOrigRef.current ?? {};
            const diff = {};
            for (const key of Object.keys(editForm)) {
                if (editForm[key] !== orig[key]) {
                    diff[key] = editForm[key];
                }
            }
            if (Object.keys(diff).length === 0) {
                setEditingId(null);
                return;
            }
            await updatePortfolio(id, diff);
            setEditingId(null);
            await loadPortfolio();
        } catch (err) {
            const msg = err?.message ?? String(err);
            if (msg.includes('404') || msg.includes('not found')) {
                alert('해당 종목을 찾을 수 없습니다. 이미 삭제되었을 수 있습니다.');
                await loadPortfolio();
            } else {
                alert('수정 실패: ' + msg);
            }
        } finally {
            setEditLoading(false);
        }
    };

    const handleDelete = async (id) => {
        try {
            await deletePortfolio(id);
            setDeleteConfirmId(null);
            await loadPortfolio();
        } catch (err) {
            const msg = err?.message ?? String(err);
            if (msg.includes('404') || msg.includes('not found')) {
                alert('해당 종목을 찾을 수 없습니다. 이미 삭제되었을 수 있습니다.');
                setDeleteConfirmId(null);
                await loadPortfolio();
            } else {
                alert('삭제 실패: ' + msg);
            }
        }
    };

    /* ── manual order ────────────────────────────────────────────── */

    const submitManualOrder = async (event) => {
        event.preventDefault();
        setManualLoading(true);
        setManualError('');
        setManualResult(null);
        try {
            const payload = {
                ticker: manualForm.code.trim(),
                action: manualForm.type === 'sell' ? 'SELL' : 'BUY',
                quantity: Number(manualForm.qty),
                price: Number(manualForm.price),
            };
            const result = await createTradeOrder(payload);
            setManualResult(result ?? { ok: true });
            if (result?.kis_result !== undefined) {
                const message =
                    typeof result.kis_result === 'string'
                        ? result.kis_result
                        : JSON.stringify(result.kis_result, null, 2);
                setKisModal(message);
            }
            await loadBalance();
        } catch (err) {
            setManualError(err?.message ?? String(err));
        } finally {
            setManualLoading(false);
        }
    };

    /* ── derived data ────────────────────────────────────────────── */

    const holdings = useMemo(() => {
        if (!balance) return [];
        if (Array.isArray(balance.holdings)) return balance.holdings;
        if (Array.isArray(balance.positions)) return balance.positions;
        if (Array.isArray(balance.items)) return balance.items;
        return [];
    }, [balance]);
    const summary = balance?.summary ?? {};
    const totalEval =
        summary.total_eval ?? balance?.total_eval ?? balance?.total_value;
    const deposit =
        summary.deposit ?? balance?.deposit ?? balance?.available_cash;

    /* Portfolio grouped by broker */
    const portfolioHoldings = portfolio?.holdings ?? [];
    const portfolioSummary = portfolio?.summary ?? {};
    const brokerGroups = useMemo(() => {
        const map = {};
        for (const item of portfolioHoldings) {
            const broker = item.broker || '기타';
            if (!map[broker]) map[broker] = [];
            map[broker].push(item);
        }
        return Object.entries(map).sort(([a], [b]) => a.localeCompare(b));
    }, [portfolioHoldings]);

    /* broker-level summary (eval_amount가 null인 종목은 안전하게 건너뜀) */
    const getBrokerSummary = (items) => {
        let totalBuy = 0;
        let totalEvalAmt = 0;
        let hasNullPrice = false;
        for (const item of items) {
            totalBuy += (item.avg_price ?? 0) * (item.quantity ?? 0);
            if (item.eval_amount != null) {
                totalEvalAmt += item.eval_amount;
            } else {
                hasNullPrice = true;
            }
        }
        const totalProfit = totalEvalAmt - totalBuy;
        const totalProfitRate = totalBuy > 0 ? (totalProfit / totalBuy) * 100 : 0;
        return { totalBuy, totalEval: totalEvalAmt, totalProfit, totalProfitRate, hasNullPrice };
    };

    /* ── broker color accents (deterministic from name) ──────────── */
    const brokerColors = useMemo(() => {
        const palette = [
            { border: 'rgba(129,140,248,0.5)', bg: 'rgba(129,140,248,0.06)' },
            { border: 'rgba(251,191,36,0.5)', bg: 'rgba(251,191,36,0.06)' },
            { border: 'rgba(52,211,153,0.5)', bg: 'rgba(52,211,153,0.06)' },
            { border: 'rgba(244,114,182,0.5)', bg: 'rgba(244,114,182,0.06)' },
            { border: 'rgba(251,146,60,0.5)', bg: 'rgba(251,146,60,0.06)' },
            { border: 'rgba(139,92,246,0.5)', bg: 'rgba(139,92,246,0.06)' },
        ];
        const map = {};
        brokerGroups.forEach(([broker], i) => {
            map[broker] = palette[i % palette.length];
        });
        return map;
    }, [brokerGroups]);

    /* ── render ───────────────────────────────────────────────────── */

    return (
        <div className="stock">
            <header className="stock-header">
                <div>
                    <p className="stock-kicker">거래 데스크</p>
                    <h1>주식 거래</h1>
                    <p className="stock-sub">
                        연결된 계좌 잔고를 확인하고 필요한 주문을 요청하세요.
                    </p>
                    <div className="stock-actions">
                        <Link className="button ghost" to="/stock">
                            주식 랩으로 돌아가기
                        </Link>
                    </div>
                </div>
                <div className="stock-card">
                    <p className="stock-card__title">계좌 요약</p>
                    <div className="stock-status">
                        <div>
                            <span>총 평가금액</span>
                            <strong>{formatNumber(totalEval)}</strong>
                        </div>
                        <div>
                            <span>예수금</span>
                            <strong>{formatNumber(deposit)}</strong>
                        </div>
                        <div>
                            <span>보유 종목</span>
                            <strong>{holdings.length}</strong>
                        </div>
                        {portfolioHoldings.length > 0 && (
                            <>
                                <div style={{ borderTop: '1px solid var(--line)', paddingTop: 8 }}>
                                    <span>포트폴리오 종목</span>
                                    <strong>{portfolioHoldings.length}</strong>
                                </div>
                                <div>
                                    <span>포트폴리오 평가</span>
                                    <strong>{formatNumber(portfolioSummary.total_eval)}</strong>
                                </div>
                                <div>
                                    <span>포트폴리오 손익</span>
                                    <strong
                                        className={`stock-profit ${profitColorClass(
                                            toNumeric(portfolioSummary.total_profit)
                                        )}`}
                                    >
                                        {formatNumber(portfolioSummary.total_profit)}
                                        {portfolioSummary.total_profit_rate != null && (
                                            <small style={{ marginLeft: 4, fontSize: 11 }}>
                                                ({formatPercent(portfolioSummary.total_profit_rate)})
                                            </small>
                                        )}
                                    </strong>
                                </div>
                            </>
                        )}
                    </div>
                    {summary.note ? (
                        <p className="stock-status__note">{summary.note}</p>
                    ) : null}
                </div>
            </header>

            {/* ── Portfolio sections (broker별) ─────────────────────── */}
            {portfolioError ? (
                <p className="stock-error">{portfolioError}</p>
            ) : null}

            {/* 총 포트폴리오 요약 + 종목 추가 */}
            <section className="stock-panel stock-panel--wide pf-section">
                <div className="stock-panel__head">
                    <div>
                        <p className="stock-panel__eyebrow">포트폴리오</p>
                        <h3>수동 입력 종목 관리</h3>
                        <p className="stock-panel__sub">
                            증권사별 보유 종목을 수동 등록하면 현재가를 자동 조회합니다. (3분 캐시)
                        </p>
                    </div>
                    <div className="stock-panel__actions">
                        {portfolioLoading ? (
                            <Loading type="spinner" message="" />
                        ) : null}
                        <button
                            className="button ghost small"
                            onClick={loadPortfolio}
                            disabled={portfolioLoading}
                        >
                            새로고침
                        </button>
                        <button
                            className="button primary small"
                            onClick={() => setAddFormOpen((v) => !v)}
                        >
                            {addFormOpen ? '취소' : '+ 종목 추가'}
                        </button>
                    </div>
                </div>

                {/* Add form */}
                {addFormOpen && (
                    <form className="pf-add-form" onSubmit={handleAddSubmit}>
                        <label>
                            증권사
                            <input
                                type="text"
                                value={addForm.broker}
                                onChange={(e) =>
                                    setAddForm((p) => ({ ...p, broker: e.target.value }))
                                }
                                placeholder="KB증권"
                                required
                            />
                        </label>
                        <label>
                            종목코드
                            <input
                                type="text"
                                value={addForm.ticker}
                                onChange={(e) =>
                                    setAddForm((p) => ({ ...p, ticker: e.target.value }))
                                }
                                placeholder="005930"
                                required
                                maxLength={6}
                            />
                        </label>
                        <label>
                            종목명
                            <input
                                type="text"
                                value={addForm.name}
                                onChange={(e) =>
                                    setAddForm((p) => ({ ...p, name: e.target.value }))
                                }
                                placeholder="삼성전자"
                                required
                            />
                        </label>
                        <label>
                            수량
                            <input
                                type="number"
                                min={1}
                                step={1}
                                value={addForm.quantity}
                                onChange={(e) =>
                                    setAddForm((p) => ({ ...p, quantity: e.target.value }))
                                }
                                required
                            />
                        </label>
                        <label>
                            평균 매입가 (원)
                            <input
                                type="number"
                                min={0}
                                step={1}
                                value={addForm.avg_price}
                                onChange={(e) =>
                                    setAddForm((p) => ({ ...p, avg_price: e.target.value }))
                                }
                                required
                            />
                        </label>
                        <button
                            className="button primary"
                            type="submit"
                            disabled={addLoading}
                        >
                            {addLoading ? '등록 중...' : '종목 등록'}
                        </button>
                        {addError && <p className="stock-error">{addError}</p>}
                    </form>
                )}

                {/* Portfolio total summary */}
                {portfolioHoldings.length > 0 && (
                    <div className="pf-total-summary">
                        {[
                            { label: '총 매입', value: portfolioSummary.total_buy },
                            { label: '총 평가', value: portfolioSummary.total_eval },
                            { label: '총 손익', value: portfolioSummary.total_profit, isProfit: true },
                            { label: '수익률', value: portfolioSummary.total_profit_rate, isRate: true },
                        ].map((s) => (
                            <div key={s.label} className="pf-total-summary__card">
                                <span>{s.label}</span>
                                <strong
                                    className={
                                        s.isProfit || s.isRate
                                            ? `stock-profit ${profitColorClass(toNumeric(s.value))}`
                                            : ''
                                    }
                                >
                                    {s.isRate ? formatPercent(s.value) : formatNumber(s.value)}
                                </strong>
                            </div>
                        ))}
                    </div>
                )}
            </section>

            {/* Each broker gets a stacked card */}
            {brokerGroups.map(([broker, items]) => {
                const bSummary = getBrokerSummary(items);
                const color = brokerColors[broker];
                return (
                    <section
                        key={broker}
                        className="stock-panel stock-panel--wide pf-broker-section"
                        style={{
                            borderColor: color?.border,
                            background: color?.bg,
                        }}
                    >
                        <div className="stock-panel__head">
                            <div>
                                <p
                                    className="stock-panel__eyebrow"
                                    style={{ color: color?.border }}
                                >
                                    {broker}
                                </p>
                                <h3>{broker} 보유 현황</h3>
                                <p className="stock-panel__sub">
                                    {items.length}종목 · 평가{' '}
                                    {formatNumber(bSummary.totalEval)} · 손익{' '}
                                    <span
                                        className={`stock-profit ${profitColorClass(
                                            bSummary.totalProfit
                                        )}`}
                                    >
                                        {formatNumber(bSummary.totalProfit)} (
                                        {formatPercent(bSummary.totalProfitRate)})
                                    </span>
                                </p>
                            </div>
                        </div>
                        <div className="stock-holdings">
                            {items.map((item) => {
                                const profitAmt = item.profit_amount;
                                const profitRate = item.profit_rate;
                                const profitAmtN = toNumeric(profitAmt);
                                const profitRateN = toNumeric(profitRate);
                                const isEditing = editingId === item.id;
                                const isDeleting = deleteConfirmId === item.id;

                                return (
                                    <div
                                        key={item.id}
                                        className="stock-holdings__item pf-item"
                                    >
                                        {isEditing ? (
                                            /* Edit mode */
                                            <div className="pf-edit-row">
                                                <div className="pf-edit-fields">
                                                    <label>
                                                        수량
                                                        <input
                                                            type="number"
                                                            min={1}
                                                            value={editForm.quantity ?? ''}
                                                            onChange={(e) =>
                                                                setEditForm((p) => ({
                                                                    ...p,
                                                                    quantity: Number(e.target.value),
                                                                }))
                                                            }
                                                        />
                                                    </label>
                                                    <label>
                                                        평균매입가
                                                        <input
                                                            type="number"
                                                            min={0}
                                                            value={editForm.avg_price ?? ''}
                                                            onChange={(e) =>
                                                                setEditForm((p) => ({
                                                                    ...p,
                                                                    avg_price: Number(e.target.value),
                                                                }))
                                                            }
                                                        />
                                                    </label>
                                                </div>
                                                <div className="pf-edit-actions">
                                                    <button
                                                        className="button primary small"
                                                        onClick={() => handleEditSave(item.id)}
                                                        disabled={editLoading}
                                                    >
                                                        {editLoading ? '저장 중...' : '저장'}
                                                    </button>
                                                    <button
                                                        className="button ghost small"
                                                        onClick={() => setEditingId(null)}
                                                    >
                                                        취소
                                                    </button>
                                                </div>
                                            </div>
                                        ) : (
                                            /* Normal display */
                                            <>
                                                <div>
                                                    <p className="stock-holdings__name">
                                                        {item.name ?? item.ticker ?? 'N/A'}
                                                    </p>
                                                    <span className="stock-holdings__code">
                                                        {item.ticker ?? ''}
                                                    </span>
                                                </div>
                                                <div className="stock-holdings__metric">
                                                    <span>수량</span>
                                                    <strong>{formatNumber(item.quantity)}</strong>
                                                </div>
                                                <div className="stock-holdings__metric">
                                                    <span>매입가</span>
                                                    <strong>{formatNumber(item.avg_price)}</strong>
                                                </div>
                                                <div className="stock-holdings__metric">
                                                    <span>현재가</span>
                                                    <strong
                                                        className={item.current_price == null ? 'pf-null-price' : ''}
                                                    >
                                                        {item.current_price != null
                                                            ? formatNumber(item.current_price)
                                                            : '조회 실패'}
                                                    </strong>
                                                </div>
                                                <div className="stock-holdings__metric">
                                                    <span>수익률</span>
                                                    <strong
                                                        className={`stock-profit ${profitColorClass(profitRateN)}`}
                                                    >
                                                        {profitRate != null
                                                            ? formatPercent(profitRate)
                                                            : '-'}
                                                    </strong>
                                                </div>
                                                <div className="stock-holdings__metric">
                                                    <span>평가손익</span>
                                                    <strong
                                                        className={`stock-profit ${profitColorClass(profitAmtN)}`}
                                                    >
                                                        {profitAmt != null
                                                            ? formatNumber(profitAmt)
                                                            : '-'}
                                                    </strong>
                                                </div>
                                                {/* action buttons */}
                                                <div className="pf-item-actions">
                                                    <button
                                                        className="button ghost small"
                                                        onClick={() => handleEditStart(item)}
                                                        title="수정"
                                                    >
                                                        ✏️
                                                    </button>
                                                    {isDeleting ? (
                                                        <>
                                                            <button
                                                                className="button ghost small pf-btn-danger"
                                                                onClick={() => handleDelete(item.id)}
                                                            >
                                                                확인
                                                            </button>
                                                            <button
                                                                className="button ghost small"
                                                                onClick={() =>
                                                                    setDeleteConfirmId(null)
                                                                }
                                                            >
                                                                취소
                                                            </button>
                                                        </>
                                                    ) : (
                                                        <button
                                                            className="button ghost small"
                                                            onClick={() =>
                                                                setDeleteConfirmId(item.id)
                                                            }
                                                            title="삭제"
                                                        >
                                                            🗑️
                                                        </button>
                                                    )}
                                                </div>
                                            </>
                                        )}
                                    </div>
                                );
                            })}
                        </div>
                    </section>
                );
            })}

            {/* ── Existing balance section ─────────────────────────── */}
            {balanceError ? <p className="stock-error">{balanceError}</p> : null}

            <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">
                        {balanceLoading ? (
                            <span className="stock-chip">조회 중</span>
                        ) : null}
                        <button
                            className="button ghost small"
                            onClick={loadBalance}
                            disabled={balanceLoading}
                        >
                            새로고침
                        </button>
                    </div>
                </div>
                <div className="stock-balance">
                    <div className="stock-balance__summary">
                        {[
                            {
                                label: '총 평가',
                                value: totalEval,
                            },
                            {
                                label: '예수금',
                                value: deposit,
                            },
                        ].map((item) => (
                            <div
                                key={item.label}
                                className="stock-balance__card"
                            >
                                <span>{item.label}</span>
                                <strong>{formatNumber(item.value)}</strong>
                            </div>
                        ))}
                    </div>
                    {holdings.length ? (
                        <div className="stock-holdings">
                            {holdings.map((item, idx) => {
                                const profitLoss = getProfitLoss(item);
                                const profitLossNumeric = toNumeric(profitLoss);
                                const profitClass = profitColorClass(profitLossNumeric);
                                const profitRate = getProfitRate(item);
                                const profitRateNumeric = toNumeric(profitRate);
                                const profitRateClass = profitColorClass(profitRateNumeric);
                                return (
                                    <div
                                        key={item.code ?? `${item.name}-${idx}`}
                                        className="stock-holdings__item"
                                    >
                                        <div>
                                            <p className="stock-holdings__name">
                                                {item.name ?? item.code ?? 'N/A'}
                                            </p>
                                            <span className="stock-holdings__code">
                                                {item.code ?? ''}
                                            </span>
                                        </div>
                                        <div className="stock-holdings__metric">
                                            <span>수량</span>
                                            <strong>
                                                {formatNumber(getQty(item))}
                                            </strong>
                                        </div>
                                        <div className="stock-holdings__metric">
                                            <span>매입가</span>
                                            <strong>
                                                {formatNumber(getBuyPrice(item))}
                                            </strong>
                                        </div>
                                        <div className="stock-holdings__metric">
                                            <span>현재가</span>
                                            <strong>
                                                {formatNumber(
                                                    getCurrentPrice(item)
                                                )}
                                            </strong>
                                        </div>
                                        <div className="stock-holdings__metric">
                                            <span>수익률</span>
                                            <strong
                                                className={`stock-profit ${profitRateClass}`}
                                            >
                                                {formatPercent(profitRate)}
                                            </strong>
                                        </div>
                                        <div className="stock-holdings__metric">
                                            <span>평가손익</span>
                                            <strong
                                                className={`stock-profit ${profitClass}`}
                                            >
                                                {formatNumber(profitLoss)}
                                            </strong>
                                        </div>
                                    </div>
                                );
                            })}
                        </div>
                    ) : (
                        <p className="stock-empty">보유 종목이 없습니다.</p>
                    )}
                </div>
            </section>

            {/* ── Manual order 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>
                <form className="stock-order" onSubmit={submitManualOrder}>
                    <label>
                        종목명/코드
                        <input
                            type="text"
                            value={manualForm.code}
                            onChange={(event) =>
                                setManualForm((prev) => ({
                                    ...prev,
                                    code: event.target.value,
                                }))
                            }
                            placeholder="005930 또는 삼성전자"
                            required
                        />
                    </label>
                    <label>
                        매수/매도
                        <select
                            value={manualForm.type}
                            onChange={(event) =>
                                setManualForm((prev) => ({
                                    ...prev,
                                    type: event.target.value,
                                }))
                            }
                        >
                            <option value="buy">매수</option>
                            <option value="sell">매도</option>
                        </select>
                    </label>
                    <label>
                        수량
                        <input
                            type="number"
                            min={1}
                            step={1}
                            value={manualForm.qty}
                            onChange={(event) =>
                                setManualForm((prev) => ({
                                    ...prev,
                                    qty: Number(event.target.value),
                                }))
                            }
                            required
                        />
                    </label>
                    <label>
                        금액(원)
                        <input
                            type="number"
                            min={0}
                            step={1}
                            value={manualForm.price}
                            onChange={(event) =>
                                setManualForm((prev) => ({
                                    ...prev,
                                    price: Number(event.target.value),
                                }))
                            }
                        />
                    </label>
                    <button
                        className="button primary"
                        type="submit"
                        disabled={manualLoading}
                    >
                        {manualLoading ? '요청 중...' : '주문 요청'}
                    </button>
                    {manualError ? (
                        <p className="stock-error">{manualError}</p>
                    ) : null}
                    {manualResult ? (
                        <div className="stock-result">
                            <p className="stock-result__title">요청 결과</p>
                            <pre>
                                {typeof manualResult === 'string'
                                    ? manualResult
                                    : JSON.stringify(manualResult, null, 2)}
                            </pre>
                        </div>
                    ) : null}
                </form>
            </section>

            {/* KIS modal */}
            {kisModal ? (
                <div className="stock-modal" role="dialog" aria-modal="true">
                    <div
                        className="stock-modal__backdrop"
                        onClick={() => setKisModal('')}
                    />
                    <div className="stock-modal__card">
                        <div className="stock-modal__head">
                            <h4>주문 결과</h4>
                            <button
                                type="button"
                                className="button ghost small"
                                onClick={() => setKisModal('')}
                            >
                                닫기
                            </button>
                        </div>
                        <pre>{kisModal}</pre>
                    </div>
                </div>
            ) : null}
        </div>
    );
};

export default StockTrade;
