begin;

set search_path to public;

-- 经营分析卡片历史展示配置修正脚本
-- 说明：
-- 1. 归一化旧版 chartPreset 中文值，统一转成当前内部预设值。
-- 2. 为老的 pie/ring/funnel 卡片补齐 showDataLabels=true，避免升级后标签丢失。
-- 3. 对非堆叠 line/bar 卡片，如果误存 dataLabelMode=total，则回退为 value。
-- 4. 对 display_text_config 为空、非法 JSON、或非对象结构的卡片，按安全对象配置修正。
-- 5. 可重复执行。

do $$
declare
  rec record;
  parsed_config jsonb;
  next_config jsonb;
  preset_text text;
  normalized_preset text;
  parse_failed boolean;
begin
  if to_regclass('public.dashboard_analytics_card_config') is null then
    raise notice 'skip upgrade_dashboard_analytics_card_display_config_pg17: table dashboard_analytics_card_config does not exist';
    return;
  end if;

  for rec in
    select
      id,
      lower(coalesce(render_type, '')) as render_type,
      display_text_config
    from dashboard_analytics_card_config
  loop
    parse_failed := false;
    parsed_config := '{}'::jsonb;

    begin
      if rec.display_text_config is null or btrim(rec.display_text_config) = '' then
        parsed_config := '{}'::jsonb;
      else
        parsed_config := rec.display_text_config::jsonb;
        if jsonb_typeof(parsed_config) <> 'object' then
          parsed_config := '{}'::jsonb;
          parse_failed := true;
        end if;
      end if;
    exception
      when others then
        parsed_config := '{}'::jsonb;
        parse_failed := true;
    end;

    next_config := parsed_config;
    preset_text := nullif(btrim(coalesce(parsed_config ->> 'chartPreset', '')), '');

    normalized_preset := case preset_text
      when '基础折线图' then 'line-basic'
      when '平滑曲线图' then 'line-smooth'
      when '面积折线图' then 'line-area'
      when '阶梯折线图（起点）' then 'line-step-start'
      when '阶梯折线图（中点）' then 'line-step-middle'
      when '阶梯折线图（终点）' then 'line-step-end'
      when '堆叠折线图' then 'line-stacked'
      when '堆积折线图' then 'line-stacked'
      when '折线图' then 'line-basic'
      when '平滑折线图' then 'line-smooth'
      when '面积图' then 'line-area'
      when '基础柱状图' then 'bar-basic'
      when '柱状图' then 'bar-basic'
      when '横向柱状图' then 'bar-horizontal'
      when '条形图' then 'bar-horizontal'
      when '堆叠柱状图' then 'bar-stacked'
      when '堆积柱状图' then 'bar-stacked'
      when '横向堆叠柱状图' then 'bar-horizontal-stacked'
      when '横向堆积柱状图' then 'bar-horizontal-stacked'
      when '堆积条形图' then 'bar-horizontal-stacked'
      when '瀑布图' then 'bar-waterfall'
      when '动态排序柱状图（单帧）' then 'bar-race'
      when '动态排序柱状图（时间帧）' then 'bar-race-timeline'
      when '基础饼图' then 'pie-basic'
      when '饼图' then 'pie-basic'
      when '圆环图' then 'pie-doughnut'
      when '环形图' then case rec.render_type
        when 'ring' then 'ring-basic'
        else 'pie-doughnut'
      end
      when '南丁格尔玫瑰图' then 'pie-rose'
      when '玫瑰图' then case rec.render_type
        when 'ring' then 'ring-rose'
        else 'pie-rose'
      end
      when '嵌套饼图' then 'pie-nested'
      when '基础圆环图' then 'ring-basic'
      when '玫瑰圆环图' then 'ring-rose'
      when '嵌套圆环图' then 'ring-nested'
      when '基础漏斗图' then 'funnel-basic'
      when '漏斗图' then 'funnel-basic'
      when '对比漏斗图' then 'funnel-contrast'
      when '多系列漏斗图' then 'funnel-multiple'
      else preset_text
    end;

    if normalized_preset is distinct from preset_text and normalized_preset is not null then
      next_config := jsonb_set(next_config, '{chartPreset}', to_jsonb(normalized_preset), true);
    end if;

    if jsonb_typeof(next_config -> 'showDataLabels') = 'string' then
      if lower(coalesce(next_config ->> 'showDataLabels', '')) in ('true', '1', 'yes', 'y', 'on', '是') then
        next_config := jsonb_set(next_config, '{showDataLabels}', 'true'::jsonb, true);
      elsif lower(coalesce(next_config ->> 'showDataLabels', '')) in ('false', '0', 'no', 'n', 'off', '否') then
        next_config := jsonb_set(next_config, '{showDataLabels}', 'false'::jsonb, true);
      end if;
    end if;

    if jsonb_typeof(next_config -> 'showLegend') = 'string' then
      if lower(coalesce(next_config ->> 'showLegend', '')) in ('true', '1', 'yes', 'y', 'on', '是') then
        next_config := jsonb_set(next_config, '{showLegend}', 'true'::jsonb, true);
      elsif lower(coalesce(next_config ->> 'showLegend', '')) in ('false', '0', 'no', 'n', 'off', '否') then
        next_config := jsonb_set(next_config, '{showLegend}', 'false'::jsonb, true);
      end if;
    end if;

    if rec.render_type in ('pie', 'ring', 'funnel') and not (next_config ? 'showDataLabels') then
      next_config := jsonb_set(next_config, '{showDataLabels}', 'true'::jsonb, true);
    end if;

    if coalesce(next_config ->> 'dataLabelMode', '') = '只显示总数' then
      next_config := jsonb_set(next_config, '{dataLabelMode}', to_jsonb('total'::text), true);
    elsif coalesce(next_config ->> 'dataLabelMode', '') = '显示每段数值' then
      next_config := jsonb_set(next_config, '{dataLabelMode}', to_jsonb('value'::text), true);
    end if;

    if rec.render_type in ('line', 'bar')
      and coalesce(next_config ->> 'dataLabelMode', '') = 'total'
      and position('stacked' in coalesce(next_config ->> 'chartPreset', '')) = 0 then
      next_config := jsonb_set(next_config, '{dataLabelMode}', to_jsonb('value'::text), true);
    end if;

    if parse_failed or next_config is distinct from parsed_config then
      update dashboard_analytics_card_config
      set display_text_config = next_config::text,
          updated_at = now()
      where id = rec.id;
    end if;
  end loop;
end
$$;

commit;
