// 追蹤個股：分群清單（持久化於 SQLite KV，與財報日曆 watchlist 分開）
import { getCachedEntry, putCachedJSON } from './db.js';

const STORE_KEY = 'stock:watchlist:v1';
const MAX_GROUPS = 24;
const MAX_SYMBOLS_PER_GROUP = 48;
const MAX_SYMBOLS_TOTAL = 200;

export const SYMBOL_RE = /^[A-Z0-9.\-]{1,12}$/;

function newGroupId() {
  return `g_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
}

export function defaultWatchlist() {
  return {
    groups: [
      { id: 'default', name: '我的追蹤', symbols: [], order: 0 },
    ],
    updatedAt: new Date().toISOString(),
  };
}

function cleanSymbol(s) {
  const sym = String(s || '').trim().toUpperCase();
  return SYMBOL_RE.test(sym) ? sym : null;
}

function normalizeGroup(g, idx) {
  const id = String(g?.id || '').trim() || newGroupId();
  const name = String(g?.name || '').trim().slice(0, 40) || '未命名分群';
  const symbols = [...new Set((g?.symbols || []).map(cleanSymbol).filter(Boolean))].slice(0, MAX_SYMBOLS_PER_GROUP);
  return { id, name, symbols, order: Number.isFinite(g?.order) ? g.order : idx };
}

/** 驗證並正規化前端／API 送來的完整結構 */
export function normalizeWatchlistPayload(raw) {
  const base = defaultWatchlist();
  if (!raw || typeof raw !== 'object') return base;
  let groups = Array.isArray(raw.groups) ? raw.groups.map(normalizeGroup) : base.groups;
  if (!groups.length) groups = base.groups;
  groups = groups.slice(0, MAX_GROUPS).sort((a, b) => a.order - b.order || a.name.localeCompare(b.name, 'zh-Hant'));
  const seenSym = new Set();
  for (const g of groups) {
    g.symbols = g.symbols.filter(sym => {
      if (seenSym.has(sym) || seenSym.size >= MAX_SYMBOLS_TOTAL) return false;
      seenSym.add(sym);
      return true;
    });
  }
  if (!groups.some(g => g.id === 'default')) {
    groups.unshift({ id: 'default', name: '我的追蹤', symbols: [], order: -1 });
  }
  groups.forEach((g, i) => { g.order = i; });
  return { groups, updatedAt: new Date().toISOString() };
}

export function getStockWatchlist() {
  const row = getCachedEntry(STORE_KEY);
  const val = row?.value;
  if (!val?.groups) return defaultWatchlist();
  return normalizeWatchlistPayload(val);
}

export function saveStockWatchlist(payload) {
  const normalized = normalizeWatchlistPayload(payload);
  putCachedJSON(STORE_KEY, normalized);
  return normalized;
}

export function allWatchlistSymbols(data) {
  const out = [];
  const seen = new Set();
  for (const g of data?.groups || []) {
    for (const sym of g.symbols || []) {
      if (!seen.has(sym)) { seen.add(sym); out.push(sym); }
    }
  }
  return out;
}