"""
同步 DDL 文件：将 2026-02-20 迁移后的变更反映到 DDL 文件中。
目标文件：
  - db/etl_feiqiu/schemas/dwd.sql（schema=dwd）
  - db/etl_feiqiu/schemas/schema_dwd_doc.sql（schema=billiards_dwd）
  - db/etl_feiqiu/schemas/dws.sql（schema=dws）
  - db/etl_feiqiu/schemas/schema_dws.sql（schema=billiards_dws）

策略：对每个 DDL 文件做精确的文本替换/追加，而非全量重写。
"""

import os
import sys
import re
from pathlib import Path
from dotenv import load_dotenv

load_dotenv(Path(__file__).resolve().parents[2] / ".env")

SCHEMAS_DIR = Path(__file__).resolve().parents[2] / "db" / "etl_feiqiu" / "schemas"

# ── 变更清单 ──────────────────────────────────────────────────────────

# 1. dim_table_ex：schema_dwd_doc.sql 缺少 14 列（dwd.sql 已有）
DIM_TABLE_EX_OLD_COLS_DOC = """\
    table_status INTEGER,
    SCD2_start_time     TIMESTAMPTZ DEFAULT now(),"""

DIM_TABLE_EX_NEW_COLS_DOC = """\
    table_status INTEGER,
    create_time TIMESTAMPTZ,
    light_status INTEGER,
    tablestatusname TEXT,
    sitename TEXT,
    applet_qr_code_url TEXT,
    audit_status INTEGER,
    charge_free INTEGER,
    delay_lights_time INTEGER,
    is_rest_area INTEGER,
    only_allow_groupon INTEGER,
    order_delay_time INTEGER,
    self_table INTEGER,
    temporary_light_second INTEGER,
    virtual_table INTEGER,
    SCD2_start_time     TIMESTAMPTZ DEFAULT now(),"""

# 2. dim_assistant_ex：两个文件都缺少 4 列
DIM_ASSISTANT_EX_OLD_COLS = """\
    serial_number BIGINT,
    SCD2_start_time     TIMESTAMPTZ,"""

DIM_ASSISTANT_EX_NEW_COLS = """\
    serial_number BIGINT,
    system_role_id BIGINT,
    job_num TEXT,
    cx_unit_price NUMERIC(18,2),
    pd_unit_price NUMERIC(18,2),
    SCD2_start_time     TIMESTAMPTZ,"""

# 3. DWD 新表定义（追加到文件末尾）
DWD_NEW_TABLES = """

-- =============================================================================
-- 2026-02-20 新增表
-- =============================================================================

CREATE TABLE IF NOT EXISTS dwd_goods_stock_summary (
    site_goods_id              BIGINT       NOT NULL,
    goods_name                 TEXT,
    goods_unit                 TEXT,
    goods_category_id          BIGINT,
    goods_category_second_id   BIGINT,
    category_name              TEXT,
    range_start_stock          NUMERIC(18,4),
    range_end_stock            NUMERIC(18,4),
    range_in                   NUMERIC(18,4),
    range_out                  NUMERIC(18,4),
    range_sale                 NUMERIC(18,4),
    range_sale_money           NUMERIC(18,2),
    range_inventory            NUMERIC(18,4),
    current_stock              NUMERIC(18,4),
    site_id                    BIGINT,
    tenant_id                  BIGINT,
    fetched_at                 TIMESTAMPTZ,
    PRIMARY KEY (site_goods_id, fetched_at)
);

COMMENT ON TABLE {schema}.dwd_goods_stock_summary IS '库存汇总明细表（事实表）。来源：ods.goods_stock_summary。按时间窗口增量加载。';


CREATE TABLE IF NOT EXISTS dwd_goods_stock_movement (
    site_goods_stock_id        BIGINT       NOT NULL,
    tenant_id                  BIGINT,
    site_id                    BIGINT,
    site_goods_id              BIGINT,
    goods_name                 TEXT,
    goods_category_id          BIGINT,
    goods_second_category_id   BIGINT,
    unit                       TEXT,
    price                      NUMERIC(18,4),
    stock_type                 INTEGER,
    change_num                 NUMERIC(18,4),
    start_num                  NUMERIC(18,4),
    end_num                    NUMERIC(18,4),
    change_num_a               NUMERIC(18,4),
    start_num_a                NUMERIC(18,4),
    end_num_a                  NUMERIC(18,4),
    remark                     TEXT,
    operator_name              TEXT,
    create_time                TIMESTAMPTZ,
    fetched_at                 TIMESTAMPTZ,
    PRIMARY KEY (site_goods_stock_id)
);

COMMENT ON TABLE {schema}.dwd_goods_stock_movement IS '库存变动流水表（事实表）。来源：ods.goods_stock_movements。按 create_time 增量加载。';
"""

# 4. DWS 新表定义（追加到文件末尾）
DWS_NEW_TABLES = """

-- =============================================================================
-- 2026-02-20 新增：库存汇总表（日/周/月）
-- =============================================================================

CREATE TABLE IF NOT EXISTS {schema}.dws_goods_stock_daily_summary (
    site_id                   BIGINT       NOT NULL,
    tenant_id                 BIGINT,
    stat_date                 DATE         NOT NULL,
    site_goods_id             BIGINT       NOT NULL,
    goods_name                TEXT,
    goods_unit                TEXT,
    goods_category_id         BIGINT,
    goods_category_second_id  BIGINT,
    category_name             TEXT,
    range_start_stock         NUMERIC,
    range_end_stock           NUMERIC,
    range_in                  NUMERIC,
    range_out                 NUMERIC,
    range_sale                NUMERIC,
    range_sale_money          NUMERIC(12,2),
    range_inventory           NUMERIC,
    current_stock             NUMERIC,
    stat_period               TEXT         NOT NULL DEFAULT 'daily',
    created_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    updated_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    PRIMARY KEY (site_id, stat_date, site_goods_id)
);

COMMENT ON TABLE {schema}.dws_goods_stock_daily_summary
    IS '库存日度汇总：按门店+日期+商品汇总库存变动';

CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_date
    ON {schema}.dws_goods_stock_daily_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_goods
    ON {schema}.dws_goods_stock_daily_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_site
    ON {schema}.dws_goods_stock_daily_summary (site_id, stat_date);


CREATE TABLE IF NOT EXISTS {schema}.dws_goods_stock_weekly_summary (
    site_id                   BIGINT       NOT NULL,
    tenant_id                 BIGINT,
    stat_date                 DATE         NOT NULL,
    site_goods_id             BIGINT       NOT NULL,
    goods_name                TEXT,
    goods_unit                TEXT,
    goods_category_id         BIGINT,
    goods_category_second_id  BIGINT,
    category_name             TEXT,
    range_start_stock         NUMERIC,
    range_end_stock           NUMERIC,
    range_in                  NUMERIC,
    range_out                 NUMERIC,
    range_sale                NUMERIC,
    range_sale_money          NUMERIC(12,2),
    range_inventory           NUMERIC,
    current_stock             NUMERIC,
    stat_period               TEXT         NOT NULL DEFAULT 'weekly',
    created_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    updated_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    PRIMARY KEY (site_id, stat_date, site_goods_id)
);

COMMENT ON TABLE {schema}.dws_goods_stock_weekly_summary
    IS '库存周度汇总：按门店+ISO周+商品汇总库存变动，stat_date 为周一日期';

CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_date
    ON {schema}.dws_goods_stock_weekly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_goods
    ON {schema}.dws_goods_stock_weekly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_site
    ON {schema}.dws_goods_stock_weekly_summary (site_id, stat_date);


CREATE TABLE IF NOT EXISTS {schema}.dws_goods_stock_monthly_summary (
    site_id                   BIGINT       NOT NULL,
    tenant_id                 BIGINT,
    stat_date                 DATE         NOT NULL,
    site_goods_id             BIGINT       NOT NULL,
    goods_name                TEXT,
    goods_unit                TEXT,
    goods_category_id         BIGINT,
    goods_category_second_id  BIGINT,
    category_name             TEXT,
    range_start_stock         NUMERIC,
    range_end_stock           NUMERIC,
    range_in                  NUMERIC,
    range_out                 NUMERIC,
    range_sale                NUMERIC,
    range_sale_money          NUMERIC(12,2),
    range_inventory           NUMERIC,
    current_stock             NUMERIC,
    stat_period               TEXT         NOT NULL DEFAULT 'monthly',
    created_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    updated_at                TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    PRIMARY KEY (site_id, stat_date, site_goods_id)
);

COMMENT ON TABLE {schema}.dws_goods_stock_monthly_summary
    IS '库存月度汇总：按门店+自然月+商品汇总库存变动，stat_date 为月首日期';

CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_date
    ON {schema}.dws_goods_stock_monthly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_goods
    ON {schema}.dws_goods_stock_monthly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_site
    ON {schema}.dws_goods_stock_monthly_summary (site_id, stat_date);
"""


def patch_file(filepath: Path, old: str, new: str, label: str) -> bool:
    """在文件中替换文本"""
    content = filepath.read_text(encoding="utf-8")
    if old not in content:
        print(f"  ⚠️ {label}: 未找到匹配文本，跳过")
        return False
    if new in content:
        print(f"  ⏭️ {label}: 已包含新内容，跳过")
        return True
    content = content.replace(old, new, 1)
    filepath.write_text(content, encoding="utf-8")
    print(f"  ✅ {label}")
    return True


def append_if_missing(filepath: Path, marker: str, content: str, label: str) -> bool:
    """如果文件中不包含 marker，则追加 content"""
    text = filepath.read_text(encoding="utf-8")
    if marker in text:
        print(f"  ⏭️ {label}: 已存在，跳过")
        return True
    text = text.rstrip() + "\n" + content
    filepath.write_text(text, encoding="utf-8")
    print(f"  ✅ {label}")
    return True


def main():
    print("=" * 60)
    print("同步 DDL 文件（2026-02-20 迁移批次）")
    print("=" * 60)

    # ── 1. schema_dwd_doc.sql：dim_table_ex 加 14 列 ──
    doc_file = SCHEMAS_DIR / "schema_dwd_doc.sql"
    print(f"\n[1] {doc_file.name}: dim_table_ex +14 列")
    patch_file(doc_file, DIM_TABLE_EX_OLD_COLS_DOC, DIM_TABLE_EX_NEW_COLS_DOC,
               "dim_table_ex 列定义")

    # ── 2. schema_dwd_doc.sql：dim_assistant_ex 加 4 列 ──
    print(f"\n[2] {doc_file.name}: dim_assistant_ex +4 列")
    patch_file(doc_file, DIM_ASSISTANT_EX_OLD_COLS, DIM_ASSISTANT_EX_NEW_COLS,
               "dim_assistant_ex 列定义（doc）")

    # ── 3. dwd.sql：dim_assistant_ex 加 4 列 ──
    dwd_file = SCHEMAS_DIR / "dwd.sql"
    print(f"\n[3] {dwd_file.name}: dim_assistant_ex +4 列")
    patch_file(dwd_file, DIM_ASSISTANT_EX_OLD_COLS, DIM_ASSISTANT_EX_NEW_COLS,
               "dim_assistant_ex 列定义（dwd）")

    # ── 4. dwd.sql：追加新表 ──
    print(f"\n[4] {dwd_file.name}: 追加 dwd_goods_stock_summary + dwd_goods_stock_movement")
    append_if_missing(dwd_file, "dwd_goods_stock_summary",
                      DWD_NEW_TABLES.format(schema="dwd"),
                      "DWD 新表")

    # ── 5. schema_dwd_doc.sql：追加新表 ──
    print(f"\n[5] {doc_file.name}: 追加 dwd_goods_stock_summary + dwd_goods_stock_movement")
    append_if_missing(doc_file, "dwd_goods_stock_summary",
                      DWD_NEW_TABLES.format(schema="billiards_dwd"),
                      "DWD 新表（doc）")

    # ── 6. dws.sql：追加库存汇总表 ──
    dws_file = SCHEMAS_DIR / "dws.sql"
    print(f"\n[6] {dws_file.name}: 追加 3 张库存汇总表")
    append_if_missing(dws_file, "dws_goods_stock_daily_summary",
                      DWS_NEW_TABLES.format(schema="dws"),
                      "DWS 库存汇总表")

    # ── 7. schema_dws.sql：追加库存汇总表 ──
    dws_doc_file = SCHEMAS_DIR / "schema_dws.sql"
    print(f"\n[7] {dws_doc_file.name}: 追加 3 张库存汇总表")
    append_if_missing(dws_doc_file, "dws_goods_stock_daily_summary",
                      DWS_NEW_TABLES.format(schema="billiards_dws"),
                      "DWS 库存汇总表（doc）")

    print("\n" + "=" * 60)
    print("DDL 同步完成")
    print("=" * 60)


if __name__ == "__main__":
    main()
