// filter-data.jsx — SDUI screening catalog (TW market)
// Mirrors the three-layer model: fields (write contract / value space),
// layout.compact (per-size-class arrangement + widget), options_by_source.
// This is the GET /screening/filter-catalog?market=TW envelope, trimmed to
// representative filters across all 8 categories.

// ── Category palette ─────────────────────────────────────────────
// One pastel hue per category, shared chroma/lightness (oklch).
const catColor = (hue) => ({
  dot:  `oklch(0.60 0.13 ${hue})`,
  tint: `oklch(0.95 0.035 ${hue})`,
  ink:  `oklch(0.45 0.11 ${hue})`,
});

const CATEGORIES = [
  { key: 'classification', label: '分類',   precedence: 10, ...catColor(255) },
  { key: 'date',           label: '日期',   precedence: 20, ...catColor(305) },
  { key: 'price',          label: '價格',   precedence: 30, ...catColor(150) },
  { key: 'volume',         label: '量能',   precedence: 40, ...catColor(195) },
  { key: 'technical',      label: '技術面', precedence: 50, ...catColor(25)  },
  { key: 'chip',           label: '籌碼面', precedence: 55, ...catColor(85)  },
  { key: 'tag',            label: '標籤',   precedence: 60, ...catColor(330) },
  { key: 'rank',           label: '排名',   precedence: 90, ...catColor(60)  },
];

// ── helpers to keep field defs terse ─────────────────────────────
const num    = (key, label, o = {}) => ({ kind: 'number', key, label, decimals: 0, required: false, default: null, range: { min: 0, max: null }, ...o });
const choice = (key, label, values, o = {}) => ({ kind: 'choice', key, label, single: true, default: values[0]?.value, options: { kind: 'static', values }, ...o });
const dyn    = (key, label, source, o = {}) => ({ kind: 'choice', key, label, single: false, options: { kind: 'dynamic', source }, ...o });
const v      = (value, label) => ({ value, label });

// min / max number pair — the highest-frequency pattern (composite #1)
const range = (unit, decimals = 0) => ([
  num('min', '最低', { unit, decimals }),
  num('max', '最高', { unit, decimals }),
]);
const rangeLayout = { kind: 'group', layout: 'horizontal', children: [
  { kind: 'ref', key: 'min', widget: 'input' },
  { kind: 'ref', key: 'max', widget: 'input' },
]};

const FILTERS = [
  // ── classification ─────────────────────────────────────────────
  {
    id: 'sector', label: '產業', category: 'classification', repeatable: false, verifiable: false,
    desc: '依 GICS 產業分類包含或排除',
    fields: [
      choice('op', '條件', [v('include', '包含'), v('exclude', '排除')]),
      dyn('values', '產業別', 'sector', { required: true }),
    ],
    layout: { nodes: [
      { kind: 'group', layout: 'vertical', children: [
        { kind: 'ref', key: 'op', widget: 'segmented' },
        { kind: 'ref', key: 'values', widget: 'dropdown' },
      ]},
    ]},
  },
  {
    id: 'board', label: '上市別', category: 'classification', repeatable: false, verifiable: false,
    fields: [ { kind: 'choice', key: 'values', label: '板別', single: false, default: ['listed'],
      options: { kind: 'static', values: [v('listed', '上市'), v('otc', '上櫃'), v('emerging', '興櫃')] } } ],
    layout: { nodes: [ { kind: 'ref', key: 'values', widget: 'checkbox' } ] },
  },
  {
    id: 'market_cap', label: '市值', category: 'classification', repeatable: false, verifiable: true,
    desc: '流通市值區間',
    fields: range('億'),
    layout: { nodes: [ rangeLayout ] },
  },

  // ── date ───────────────────────────────────────────────────────
  {
    id: 'earnings_date', label: '財報公布', category: 'date', repeatable: false, verifiable: false,
    fields: [ choice('window', '範圍', [v('this_week', '本週'), v('this_month', '本月'), v('this_quarter', '本季'), v('next_month', '下月')]) ],
    layout: { nodes: [ { kind: 'ref', key: 'window', widget: 'dropdown' } ] },
  },
  {
    id: 'ex_date', label: '除權息日', category: 'date', repeatable: false, verifiable: false,
    fields: [ { kind: 'date', key: 'on', label: '日期' } ],
    layout: { nodes: [ { kind: 'ref', key: 'on', widget: 'date_picker' } ] },
  },

  // ── price ──────────────────────────────────────────────────────
  {
    id: 'price', label: '股價', category: 'price', repeatable: false, verifiable: true,
    desc: '收盤價區間',
    fields: range('元', 2),
    layout: { nodes: [ rangeLayout ] },
  },
  {
    id: 'pct_change', label: '漲跌幅', category: 'price', repeatable: false, verifiable: true,
    desc: '當日相對昨收',
    fields: range('%', 2),
    layout: { nodes: [ rangeLayout ] },
  },

  // ── volume ─────────────────────────────────────────────────────
  {
    id: 'volume', label: '成交量', category: 'volume', repeatable: false, verifiable: true,
    desc: '當日成交張數',
    fields: range('張'),
    layout: { nodes: [ rangeLayout ] },
  },
  {
    id: 'turnover', label: '成交值', category: 'volume', repeatable: false, verifiable: true,
    fields: range('億', 1),
    layout: { nodes: [ rangeLayout ] },
  },
  {
    id: 'vol_ratio', label: '量比', category: 'volume', repeatable: false, verifiable: true,
    desc: '當日量 / 近 5 日均量',
    fields: [ num('min', '至少', { decimals: 1, default: 2, unit: '×' }) ],
    layout: { nodes: [ { kind: 'ref', key: 'min', widget: 'input' } ] },
  },

  // ── technical ──────────────────────────────────────────────────
  {
    id: 'ma_cross', label: '均線交叉', category: 'technical', repeatable: true, verifiable: true,
    desc: '快慢線黃金 / 死亡交叉',
    fields: [
      num('fast', '快線', { required: true, default: 20, range: { min: 2, max: 150 } }),
      num('slow', '慢線', { required: true, default: 60, range: { min: 2, max: 150 } }),
      choice('timeframe', '週期', [v('5m', '5分'), v('15m', '15分'), v('1h', '1時'), v('4h', '4時'), v('1d', '日')], { default: '1d' }),
      choice('direction', '方向', [v('golden', '黃金交叉'), v('death', '死亡交叉')]),
    ],
    layout: { nodes: [
      { kind: 'group', layout: 'horizontal', children: [
        { kind: 'ref', key: 'fast', widget: 'input' },
        { kind: 'ref', key: 'slow', widget: 'input' },
      ]},
      { kind: 'ref', key: 'timeframe', widget: 'dropdown' },
      { kind: 'ref', key: 'direction', widget: 'segmented' },
    ]},
  },
  {
    id: 'kd', label: 'KD 指標', category: 'technical', repeatable: true, verifiable: true,
    desc: '隨機指標事件',
    fields: [
      num('period', '週期', { required: true, default: 9, range: { min: 2, max: 60 } }),
      choice('event', '事件', [v('overbought', '超買'), v('oversold', '超賣'), v('golden', '黃金交叉'), v('death', '死亡交叉')]),
      num('threshold', '門檻 (K 值)', { required: true, default: 80, range: { min: 0, max: 100 } }),
    ],
    // when: 門檻只在超買 / 超賣事件下出現 — 交叉事件不需要門檻
    layout: { nodes: [
      { kind: 'ref', key: 'period', widget: 'input' },
      { kind: 'ref', key: 'event', widget: 'dropdown' },
      { kind: 'when', key: 'event', equals: ['overbought', 'oversold'], children: [
        { kind: 'ref', key: 'threshold', widget: 'input' },
      ]},
    ]},
  },
  {
    id: 'bias', label: '乖離率', category: 'technical', repeatable: true, verifiable: true,
    fields: [
      num('ma', '均線 (日)', { required: true, default: 20, range: { min: 2, max: 240 } }),
      ...range('%', 1),
    ],
    layout: { nodes: [
      { kind: 'ref', key: 'ma', widget: 'input' },
      rangeLayout,
    ]},
  },

  // ── chip ───────────────────────────────────────────────────────
  {
    id: 'foreign_flow', label: '外資買賣超', category: 'chip', repeatable: true, verifiable: true,
    desc: '連續天數 + 方向 + 張數區間',
    fields: [
      num('days', '天數', { required: true, default: 5, range: { min: 1, max: 60 } }),
      choice('direction', '方向', [v('buy', '買超'), v('sell', '賣超')]),
      ...range('張'),
    ],
    layout: { nodes: [
      { kind: 'group', layout: 'horizontal', children: [
        { kind: 'ref', key: 'days', widget: 'input' },
        { kind: 'ref', key: 'direction', widget: 'segmented' },
      ]},
      rangeLayout,
    ]},
  },
  {
    id: 'trust_flow', label: '投信買賣超', category: 'chip', repeatable: true, verifiable: true,
    fields: [
      num('days', '天數', { required: true, default: 3, range: { min: 1, max: 60 } }),
      choice('direction', '方向', [v('buy', '買超'), v('sell', '賣超')]),
      ...range('張'),
    ],
    layout: { nodes: [
      { kind: 'group', layout: 'horizontal', children: [
        { kind: 'ref', key: 'days', widget: 'input' },
        { kind: 'ref', key: 'direction', widget: 'segmented' },
      ]},
      rangeLayout,
    ]},
  },

  // ── tag ────────────────────────────────────────────────────────
  {
    id: 'concept', label: '概念股', category: 'tag', repeatable: false, verifiable: false,
    desc: '主題 / 概念標籤',
    fields: [ dyn('values', '標籤', 'tag', { required: true }) ],
    layout: { nodes: [ { kind: 'ref', key: 'values', widget: 'dropdown' } ] },
  },
  {
    id: 'index_member', label: '指數成分', category: 'tag', repeatable: false, verifiable: false,
    fields: [ { kind: 'choice', key: 'values', label: '指數', single: false, default: [],
      options: { kind: 'static', values: [v('twse50', '台灣50'), v('twse100', '中型100'), v('tpex50', '櫃買50'), v('hdiv', '高股息')] } } ],
    layout: { nodes: [ { kind: 'ref', key: 'values', widget: 'checkbox' } ] },
  },

  // ── rank ───────────────────────────────────────────────────────
  {
    id: 'rank', label: '排名', category: 'rank', repeatable: true, verifiable: false,
    desc: '依指標取前 / 後段 — 含巢狀 metric',
    fields: [
      choice('scope', '範圍', [v('universe', '全市場'), v('survivors', '已篩選')]),
      { kind: 'metric', key: 'metric', label: '排名指標', source: 'rankable_metrics' },
      choice('mode', '模式', [v('pct', '百分位'), v('count', '檔數')]),
      num('k', '取', { required: true, default: 20, decimals: 0 }),
      choice('direction', '方向', [v('top', '前段'), v('bottom', '後段')]),
      dyn('partition_by', '分組依據', 'rank_partitions', { required: false, single: true }),
    ],
    layout: { nodes: [
      { kind: 'ref', key: 'scope', widget: 'segmented' },
      { kind: 'ref', key: 'metric', widget: 'metric' },
      { kind: 'group', layout: 'horizontal', children: [
        { kind: 'ref', key: 'direction', widget: 'segmented' },
        { kind: 'ref', key: 'k', widget: 'input' },
      ]},
      { kind: 'ref', key: 'mode', widget: 'segmented' },
      { kind: 'ref', key: 'partition_by', widget: 'dropdown' },
    ]},
  },
];

const OPTIONS_BY_SOURCE = {
  sector: ['半導體', '電子零組件', '金融保險', '航運', '鋼鐵', '塑膠', '生技醫療', '觀光餐旅', '電機機械', '食品', '營建', '綠能環保'],
  tag: ['AI 伺服器', 'CPO 矽光子', '高股息', '重電', '機器人', '低軌衛星', '軍工', '散熱', '網通', '電動車', '玻璃基板', '先進封裝'],
  rank_partitions: ['產業', '市場別', '市值級距'],
};

const RANKABLE_METRICS = [
  { kind: 'avg_vol', label: '均量', params: [ num('window', '區間 (日)', { required: true, default: 20, range: { min: 1, max: 120 } }) ] },
  { kind: 'rsi',     label: 'RSI',  params: [ num('period', '週期', { required: true, default: 14, range: { min: 2, max: 60 } }) ] },
  { kind: 'pct_chg', label: '漲跌幅', params: [
      num('window', '區間 (日)', { required: true, default: 5, range: { min: 1, max: 240 } }),
      choice('baseline', '基準', [v('close', '昨收'), v('open', '開盤')]),
  ] },
  { kind: 'turnover', label: '成交值', params: [ num('window', '區間 (日)', { required: true, default: 5, range: { min: 1, max: 60 } }) ] },
  { kind: 'mkt_cap',  label: '市值',  params: [] },
  { kind: 'yield',    label: '殖利率', params: [] },
];

const CATALOG = {
  schema_version: 1,
  market: 'TW',
  categories: CATEGORIES,
  filters: FILTERS,
  options_by_source: OPTIONS_BY_SOURCE,
  rankable_metrics: RANKABLE_METRICS,
};

// Lookups
const CAT_BY_KEY = Object.fromEntries(CATEGORIES.map(c => [c.key, c]));
const FILTERS_BY_CAT = (() => {
  const out = {};
  for (const c of CATEGORIES) out[c.key] = [];
  for (const f of FILTERS) (out[f.category] = out[f.category] || []).push(f);
  return out;
})();
const FILTER_BY_ID = Object.fromEntries(FILTERS.map(f => [f.id, f]));

// Build default value object for a filter from its field defaults.
function defaultsFor(filter) {
  const out = {};
  for (const f of filter.fields) {
    if (f.kind === 'metric') out[f.key] = null;
    else if (f.kind === 'choice' && !f.single) out[f.key] = f.default ? [...f.default] : [];
    else out[f.key] = f.default ?? null;
  }
  return out;
}

Object.assign(window, {
  CATALOG, CATEGORIES, FILTERS, CAT_BY_KEY, FILTERS_BY_CAT, FILTER_BY_ID,
  RANKABLE_METRICS, OPTIONS_BY_SOURCE, defaultsFor,
});
