/* ─────────────────────────────────────────────
   로또 공통 유틸리티
───────────────────────────────────────────── */
import React from 'react';

export const fmtKST = (value) => value?.replace('T', ' ') ?? '';

export const fmtWon = (n) => {
    if (n == null || isNaN(Number(n))) return '-';
    return new Intl.NumberFormat('ko-KR').format(Math.round(Number(n))) + '원';
};

export const ballClass = (n) => {
    if (n <= 10) return 'lotto-ball range-a';
    if (n <= 20) return 'lotto-ball range-b';
    if (n <= 30) return 'lotto-ball range-c';
    if (n <= 40) return 'lotto-ball range-d';
    return 'lotto-ball range-e';
};

export const Ball = ({ n }) => <span className={ballClass(n)}>{n}</span>;

export const NumberRow = ({ nums }) => (
    <div className="lotto-row">
        {nums.map((n) => <Ball key={n} n={n} />)}
    </div>
);

/* ─────────────────────────────────────────────
   통계 헬퍼
───────────────────────────────────────────── */
export const bucketOrder = ['1-10', '11-20', '21-30', '31-40', '41-45'];
export const STATS_CACHE_KEY = 'lotto_stats_v1';
export const BEST_PICKS_DEFAULT_SHOW = 5;

export const readStatsCache = () => {
    if (typeof window === 'undefined') return null;
    try {
        const raw = localStorage.getItem(STATS_CACHE_KEY);
        if (!raw) return null;
        const parsed = JSON.parse(raw);
        if (!parsed || !Array.isArray(parsed.frequency)) return null;
        return parsed;
    } catch { return null; }
};

export const writeStatsCache = (data) => {
    if (typeof window === 'undefined') return;
    try { localStorage.setItem(STATS_CACHE_KEY, JSON.stringify(data)); } catch {}
};

export const buildFrequencySeries = (frequency) => {
    const map = new Map();
    (frequency ?? []).forEach((item) => {
        const number = Number(item?.number);
        const count = Number(item?.count) || 0;
        if (Number.isFinite(number) && number >= 1 && number <= 45) map.set(number, count);
    });
    const series = Array.from({ length: 45 }, (_, idx) => ({
        number: idx + 1, count: map.get(idx + 1) ?? 0,
    }));
    const max = Math.max(1, ...series.map((item) => item.count));
    return { series, max };
};

export const buildMetricsFromCounts = (counts) => {
    if (!counts?.length) return null;
    const total = counts.reduce((acc, v) => acc + v, 0);
    if (!total) return null;
    const min = Math.min(...counts), max = Math.max(...counts);
    const odd = counts.reduce((acc, v, idx) => (idx % 2 === 0 ? acc + v : acc), 0);
    const even = total - odd;
    const buckets = {
        '1-10': counts.slice(0, 10).reduce((a, b) => a + b, 0),
        '11-20': counts.slice(10, 20).reduce((a, b) => a + b, 0),
        '21-30': counts.slice(20, 30).reduce((a, b) => a + b, 0),
        '31-40': counts.slice(30, 40).reduce((a, b) => a + b, 0),
        '41-45': counts.slice(40, 45).reduce((a, b) => a + b, 0),
    };
    return { sum: total, min, max, range: max - min, odd, even, buckets };
};

export const buildMetricsFromFrequency = (frequency) => {
    if (!frequency?.length) return null;
    const counts = Array.from({ length: 45 }, () => 0);
    frequency.forEach((item) => {
        const number = Number(item?.number), count = Number(item?.count) || 0;
        if (number >= 1 && number <= 45) counts[number - 1] = count;
    });
    return buildMetricsFromCounts(counts);
};

export const buildMetricsFromHistory = (items) => {
    if (!items?.length) return null;
    const counts = Array.from({ length: 45 }, () => 0);
    items.forEach((item) => {
        (item?.numbers ?? []).forEach((value) => {
            const number = Number(value);
            if (number >= 1 && number <= 45) counts[number - 1] += 1;
        });
    });
    return buildMetricsFromCounts(counts);
};

export const toBucketEntries = (metrics) => {
    if (!metrics?.buckets) return [];
    const ordered = bucketOrder
        .filter((key) => Object.prototype.hasOwnProperty.call(metrics.buckets, key))
        .map((key) => [key, metrics.buckets[key]]);
    const rest = Object.entries(metrics.buckets)
        .filter(([key]) => !bucketOrder.includes(key))
        .sort((a, b) => Number(a[0].split('-')[0]) - Number(b[0].split('-')[0]));
    return [...ordered, ...rest];
};

export const emptyPurchaseForm = () => ({ draw_no: '', amount: 5000, sets: 5, prize: 0, note: '' });

export const copyNumbers = async (nums) => {
    const text = nums.join(', ');
    try { await navigator.clipboard.writeText(text); alert(`복사 완료: ${text}`); }
    catch { prompt('복사해서 사용하세요:', text); }
};

/* 종합 추론 상수 */
export const METHOD_META = {
    frequency:   { label: '빈도 Z-score',  desc: '역대 출현 빈도가 기댓값보다 높은 번호', color: '#818cf8', icon: '📊' },
    fingerprint: { label: '조합 지문',     desc: '역대 당첨 조합의 합계·홀짝·구간 분포에 맞는 번호', color: '#fbbf24', icon: '🔏' },
    gap:         { label: '갭 분석',       desc: '가장 오래 등장하지 않은 오버듀 번호', color: '#34d399', icon: '⏳' },
    cooccur:     { label: '공동 출현',     desc: '역대에 함께 출현한 빈도가 높은 번호', color: '#f472b6', icon: '🔗' },
    diversity:   { label: '다양성',        desc: '구간 커버리지와 번호 범위를 극대화한 번호', color: '#fb923c', icon: '🌈' },
};

export const METHOD_ORDER = ['fingerprint', 'frequency', 'gap', 'cooccur', 'diversity'];

export const SCORE_META = [
    { key: 'score_fingerprint', label: '조합 지문',  color: '#fbbf24', weight: 30 },
    { key: 'score_frequency',   label: '빈도 Z',     color: '#818cf8', weight: 25 },
    { key: 'score_gap',         label: '갭 분석',    color: '#34d399', weight: 20 },
    { key: 'score_cooccur',     label: '공동 출현',  color: '#f472b6', weight: 15 },
    { key: 'score_diversity',   label: '다양성',     color: '#fb923c', weight: 10 },
];
