#!/usr/bin/env python3
import argparse
import subprocess
import sys


def _sql_escape(value: str) -> str:
    return value.replace("'", "''")


def build_sql(keyword: str, days: int, limit: int) -> str:
    kw = _sql_escape(keyword.strip())
    return f"""
USE [JSDataMiddlePlatform];
SET NOCOUNT ON;

DECLARE @kw nvarchar(100) = N'{kw}';
DECLARE @days int = {days};
DECLARE @limit int = {limit};
DECLARE @start_time datetime2 = DATEADD(day, -@days, GETDATE());
DECLARE @end_time datetime2 = GETDATE();
DECLARE @has_exact bit = 0;

IF EXISTS (SELECT 1 FROM dbo.jst_sku WITH (NOLOCK) WHERE sku_id = @kw)
    SET @has_exact = 1;

IF OBJECT_ID('tempdb..#matched_sku') IS NOT NULL
    DROP TABLE #matched_sku;

SELECT TOP (300)
    s.sku_id,
    s.i_id AS style_code,
    s.other_1 AS spu,
    s.name AS sku_name,
    s.short_name,
    s.properties_value,
    s.color,
    s.item_type,
    s.category,
    s.brand,
    s.vc_name,
    s.supplier_name,
    s.supplier_sku_id,
    s.sku_code,
    s.sale_price,
    s.cost_price,
    s.purchase_price,
    s.market_price,
    s.weight,
    s.l,
    s.w,
    s.h,
    s.unit,
    s.labels,
    s.other_2 AS board_type,
    s.other_10 AS board_material,
    s.other_3 AS default_warehouse,
    s.other_5 AS sku_status,
    s.other_7 AS product_no,
    s.pic AS preview_pic_url,
    s.pic_big AS preview_pic_big_url,
    s.created,
    s.modified,
    CASE
        WHEN s.sku_id = @kw THEN 0
        WHEN s.i_id = @kw THEN 1
        WHEN s.other_1 = @kw THEN 2
        WHEN s.other_7 = @kw THEN 3
        WHEN s.sku_id LIKE @kw + '%' THEN 4
        WHEN s.name LIKE @kw + '%' THEN 5
        ELSE 9
    END AS match_rank
INTO #matched_sku
FROM dbo.jst_sku AS s WITH (NOLOCK)
WHERE ISNULL(NULLIF(@kw, ''), '') <> ''
  AND (
      (@has_exact = 1 AND s.sku_id = @kw)
      OR (
          @has_exact = 0
          AND (
              s.sku_id LIKE '%' + @kw + '%'
              OR s.i_id LIKE '%' + @kw + '%'
              OR s.other_1 LIKE '%' + @kw + '%'
              OR s.name LIKE '%' + @kw + '%'
              OR s.short_name LIKE '%' + @kw + '%'
              OR s.other_7 LIKE '%' + @kw + '%'
          )
      )
  )
ORDER BY
    CASE
        WHEN s.sku_id = @kw THEN 0
        WHEN s.i_id = @kw THEN 1
        WHEN s.other_1 = @kw THEN 2
        WHEN s.other_7 = @kw THEN 3
        WHEN s.sku_id LIKE @kw + '%' THEN 4
        WHEN s.name LIKE @kw + '%' THEN 5
        ELSE 9
    END,
    s.modified DESC;

-- 1) 产品基础信息（含SKU名称/成本/材质/预览图 + 扩展字段）
SELECT TOP (@limit)
    sku_id,
    sku_name,
    short_name,
    style_code,
    spu,
    product_no,
    sku_code,
    properties_value,
    color,
    item_type,
    category,
    brand,
    supplier_name,
    supplier_sku_id,
    cost_price,
    purchase_price,
    sale_price,
    market_price,
    board_type,
    board_material,
    default_warehouse,
    sku_status,
    labels,
    weight,
    l,
    w,
    h,
    unit,
    preview_pic_url,
    preview_pic_big_url,
    created,
    modified
FROM #matched_sku
ORDER BY match_rank ASC, modified DESC;

IF OBJECT_ID('tempdb..#afs') IS NOT NULL
    DROP TABLE #afs;

SELECT
    NULLIF(a.undefined10, '') AS sku_id,
    ISNULL(NULLIF(a.undefined36, ''), 'unknown') AS sku_name,
    ISNULL(NULLIF(a.undefined8, ''), 'unknown') AS shop_name,
    NULLIF(a.undefined2, '') AS order_id,
    ISNULL(NULLIF(a.undefined56, ''), '未标注') AS afs_type,
    ISNULL(NULLIF(a.undefined58, ''), '未标注') AS afs_result,
    ISNULL(NULLIF(a.undefined57, ''), '') AS native_reason,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined20, '')) AS order_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined30, '')) AS shipped_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined37, '')) AS pre_ship_apply_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined40, '')) AS pre_ship_return_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined46, '')) AS post_ship_apply_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined49, '')) AS post_ship_return_qty,
    TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined52, '')) AS refund_amount
INTO #afs
FROM dbo.jst_goods_profit_kpi_items_afs AS a WITH (NOLOCK)
WHERE a.createdAt >= @start_time
  AND a.createdAt < @end_time
  AND ISNULL(NULLIF(a.undefined2, ''), '') <> ''
  AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%配件%'
  AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%特殊单%'
  AND NULLIF(a.undefined10, '') IN (SELECT sku_id FROM #matched_sku);

IF OBJECT_ID('tempdb..#afs_orders') IS NOT NULL
    DROP TABLE #afs_orders;

SELECT DISTINCT order_id
INTO #afs_orders
FROM #afs
WHERE ISNULL(order_id, '') <> '';

IF OBJECT_ID('tempdb..#chat_latest') IS NOT NULL
    DROP TABLE #chat_latest;

WITH chat_rank AS (
    SELECT
        NULLIF(c.orderNo, '') AS order_id,
        ISNULL(NULLIF(c.mainReason, ''), '') AS main_reason,
        ISNULL(NULLIF(c.secondReason, ''), '') AS second_reason,
        ISNULL(NULLIF(c.thirdReason, ''), '') AS third_reason,
        c.createdAt,
        ROW_NUMBER() OVER (
            PARTITION BY NULLIF(c.orderNo, '')
            ORDER BY c.createdAt DESC, c.id DESC
        ) AS rn
    FROM dbo.pc_kfChatLog AS c WITH (NOLOCK)
    INNER JOIN #afs_orders AS o
        ON o.order_id = NULLIF(c.orderNo, '')
)
SELECT
    order_id,
    main_reason,
    second_reason,
    third_reason
INTO #chat_latest
FROM chat_rank
WHERE rn = 1;

IF OBJECT_ID('tempdb..#afs_enriched') IS NOT NULL
    DROP TABLE #afs_enriched;

SELECT
    af.*,
    CASE
        WHEN ISNULL(NULLIF(af.native_reason, ''), '') <> '' THEN af.native_reason
        WHEN ISNULL(NULLIF(cl.main_reason, ''), '') <> '' THEN cl.main_reason
        ELSE '未标注'
    END AS reason_l1,
    CASE
        WHEN ISNULL(NULLIF(cl.second_reason, ''), '') <> '' THEN cl.second_reason
        ELSE '未标注'
    END AS reason_l2,
    CASE
        WHEN ISNULL(NULLIF(cl.third_reason, ''), '') <> '' THEN cl.third_reason
        ELSE '未标注'
    END AS reason_l3,
    CASE
        WHEN ISNULL(NULLIF(af.native_reason, ''), '') <> '' THEN 'afs_reason'
        WHEN ISNULL(NULLIF(cl.main_reason, ''), '') <> '' THEN 'chat_main_reason'
        ELSE 'unknown'
    END AS reason_source
INTO #afs_enriched
FROM #afs AS af
LEFT JOIN #chat_latest AS cl
    ON cl.order_id = af.order_id;

-- 2) 最近N天产品出货/售后件数（件数优先）
SELECT TOP (@limit)
    ae.sku_id,
    MAX(COALESCE(ms.sku_name, ae.sku_name)) AS sku_name,
    COUNT(*) AS afs_record_count,
    COUNT(DISTINCT ae.order_id) AS order_count,
    SUM(ISNULL(ae.order_qty, 0)) AS order_qty_sum,
    SUM(ISNULL(ae.shipped_qty, 0)) AS shipped_qty_sum,
    SUM(CASE WHEN ISNULL(ae.refund_amount, 0) > 0 THEN 1 ELSE 0 END) AS refund_order_count
FROM #afs_enriched AS ae
LEFT JOIN #matched_sku AS ms
    ON ms.sku_id = ae.sku_id
GROUP BY ae.sku_id
ORDER BY shipped_qty_sum DESC, order_count DESC;

-- 3) 最近N天该产品的店铺分布（件数）
SELECT TOP (@limit)
    ae.shop_name,
    COUNT(DISTINCT ae.order_id) AS order_count,
    SUM(ISNULL(ae.order_qty, 0)) AS order_qty_sum,
    SUM(ISNULL(ae.shipped_qty, 0)) AS shipped_qty_sum,
    SUM(CASE WHEN ISNULL(ae.refund_amount, 0) > 0 THEN 1 ELSE 0 END) AS refund_order_count
FROM #afs_enriched AS ae
GROUP BY ae.shop_name
ORDER BY shipped_qty_sum DESC, order_count DESC;

IF OBJECT_ID('tempdb..#freight') IS NOT NULL
    DROP TABLE #freight;

SELECT
    NULLIF(f.sku_id, '') AS sku_id,
    NULLIF(f.so_id, '') AS so_id,
    ISNULL(NULLIF(f.receiver_state, ''), '未知') AS receiver_state,
    CASE
        WHEN REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(NULLIF(f.receiver_state,''),'未知'),'省',''),'市',''),'壮族自治区',''),'回族自治区',''),'维吾尔自治区',''),'自治区',''),'特别行政区',''),'地区','')
             IN ('上海','江苏','浙江','安徽') THEN '一区'
        WHEN REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(NULLIF(f.receiver_state,''),'未知'),'省',''),'市',''),'壮族自治区',''),'回族自治区',''),'维吾尔自治区',''),'自治区',''),'特别行政区',''),'地区','')
             IN ('北京','天津','河北','山东','河南','湖北','湖南','江西','福建','广东') THEN '二区'
        WHEN REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(NULLIF(f.receiver_state,''),'未知'),'省',''),'市',''),'壮族自治区',''),'回族自治区',''),'维吾尔自治区',''),'自治区',''),'特别行政区',''),'地区','')
             IN ('辽宁','吉林','黑龙江','山西','陕西','四川','重庆','贵州','云南','广西','海南','内蒙古','甘肃','宁夏','青海','新疆','西藏') THEN '三区'
        ELSE '未分区'
    END AS freight_zone,
    ISNULL(NULLIF(f.expressName, ''), 'unknown') AS express_name,
    TRY_CONVERT(decimal(18, 2), f.freightCost) AS freight_cost,
    TRY_CONVERT(decimal(18, 2), f.weight) AS freight_weight,
    f.send_date
INTO #freight
FROM dbo.fys_jstFreightCostDetail AS f WITH (NOLOCK)
WHERE f.send_date >= @start_time
  AND f.send_date < @end_time
  AND ISNULL(NULLIF(f.sku_id, ''), '') <> ''
  AND NULLIF(f.sku_id, '') IN (SELECT sku_id FROM #matched_sku);

-- 4) 最近N天一区/二区/三区运费（按SKU）
SELECT TOP (@limit)
    fr.sku_id,
    fr.freight_zone,
    COUNT(*) AS freight_record_count,
    COUNT(DISTINCT fr.so_id) AS order_count,
    SUM(ISNULL(fr.freight_cost, 0)) AS freight_cost_sum,
    AVG(ISNULL(fr.freight_cost, 0)) AS avg_freight_cost,
    AVG(ISNULL(fr.freight_weight, 0)) AS avg_weight
FROM #freight AS fr
GROUP BY fr.sku_id, fr.freight_zone
ORDER BY
    CASE fr.freight_zone WHEN '一区' THEN 1 WHEN '二区' THEN 2 WHEN '三区' THEN 3 ELSE 9 END,
    order_count DESC;

-- 5) 最近N天省份运费TOP（按SKU）
SELECT TOP (@limit)
    fr.sku_id,
    fr.receiver_state,
    COUNT(DISTINCT fr.so_id) AS order_count,
    SUM(ISNULL(fr.freight_cost, 0)) AS freight_cost_sum,
    AVG(ISNULL(fr.freight_cost, 0)) AS avg_freight_cost,
    AVG(ISNULL(fr.freight_weight, 0)) AS avg_weight
FROM #freight AS fr
GROUP BY fr.sku_id, fr.receiver_state
ORDER BY order_count DESC, freight_cost_sum DESC;

-- 6) 最近N天售后总览（该SKU）
SELECT TOP (@limit)
    ae.sku_id,
    COUNT(*) AS afs_record_count,
    COUNT(DISTINCT ae.order_id) AS afs_order_count,
    SUM(ISNULL(ae.shipped_qty, 0)) AS shipped_qty_sum,
    SUM(ISNULL(ae.pre_ship_apply_qty, 0) + ISNULL(ae.post_ship_apply_qty, 0)) AS apply_qty_sum,
    SUM(ISNULL(ae.pre_ship_return_qty, 0) + ISNULL(ae.post_ship_return_qty, 0)) AS return_qty_sum,
    SUM(CASE WHEN ISNULL(ae.refund_amount, 0) > 0 THEN 1 ELSE 0 END) AS refund_order_count,
    SUM(ISNULL(ae.refund_amount, 0)) AS refund_amount_sum
FROM #afs_enriched AS ae
GROUP BY ae.sku_id
ORDER BY afs_record_count DESC;

-- 7) 最近N天售后类型/结果矩阵（该SKU）
SELECT TOP (@limit)
    ae.sku_id,
    ae.afs_type,
    ae.afs_result,
    COUNT(*) AS afs_record_count,
    COUNT(DISTINCT ae.order_id) AS order_count,
    SUM(ISNULL(ae.shipped_qty, 0)) AS shipped_qty_sum,
    SUM(CASE WHEN ISNULL(ae.refund_amount, 0) > 0 THEN 1 ELSE 0 END) AS refund_order_count
FROM #afs_enriched AS ae
GROUP BY ae.sku_id, ae.afs_type, ae.afs_result
ORDER BY afs_record_count DESC, order_count DESC;

-- 8) 最近N天售后原因TOP（该SKU）
SELECT TOP (@limit)
    ae.sku_id,
    ae.reason_l1,
    ae.reason_l2,
    ae.reason_l3,
    ae.reason_source,
    COUNT(*) AS afs_record_count,
    COUNT(DISTINCT ae.order_id) AS order_count,
    SUM(ISNULL(ae.shipped_qty, 0)) AS shipped_qty_sum,
    SUM(CASE WHEN ISNULL(ae.refund_amount, 0) > 0 THEN 1 ELSE 0 END) AS refund_order_count
FROM #afs_enriched AS ae
GROUP BY ae.sku_id, ae.reason_l1, ae.reason_l2, ae.reason_l3, ae.reason_source
ORDER BY afs_record_count DESC, order_count DESC;

IF OBJECT_ID('tempdb..#inv_latest') IS NOT NULL
    DROP TABLE #inv_latest;

WITH inv_rank AS (
    SELECT
        NULLIF(i.sku_id, '') AS sku_id,
        TRY_CONVERT(decimal(18, 2), i.qty) AS stock_qty,
        TRY_CONVERT(decimal(18, 2), i.order_lock) AS order_lock_qty,
        TRY_CONVERT(decimal(18, 2), i.pick_lock) AS pick_lock_qty,
        TRY_CONVERT(decimal(18, 2), i.lock_qty) AS lock_qty,
        TRY_CONVERT(decimal(18, 2), i.virtual_qty) AS virtual_qty,
        TRY_CONVERT(decimal(18, 2), i.defective_qty) AS defective_qty,
        TRY_CONVERT(decimal(18, 2), i.purchase_qty) AS purchase_qty,
        TRY_CONVERT(decimal(18, 2), i.return_qty) AS return_qty,
        TRY_CONVERT(decimal(18, 2), i.in_qty) AS in_qty,
        TRY_CONVERT(decimal(18, 2), i.min_qty) AS min_qty,
        TRY_CONVERT(decimal(18, 2), i.max_qty) AS max_qty,
        i.wms_co_id,
        i.name AS inventory_note,
        COALESCE(i.updateTime, i.modified, i.createTime) AS inventory_snapshot_time,
        ROW_NUMBER() OVER (
            PARTITION BY NULLIF(i.sku_id, '')
            ORDER BY COALESCE(i.updateTime, i.modified, i.createTime) DESC, i.Id DESC
        ) AS rn
    FROM dbo.jst_inventoryInfo AS i WITH (NOLOCK)
    WHERE NULLIF(i.sku_id, '') IN (SELECT sku_id FROM #matched_sku)
)
SELECT
    sku_id,
    stock_qty,
    order_lock_qty,
    pick_lock_qty,
    lock_qty,
    virtual_qty,
    defective_qty,
    purchase_qty,
    return_qty,
    in_qty,
    min_qty,
    max_qty,
    wms_co_id,
    inventory_note,
    inventory_snapshot_time,
    CASE
        WHEN ISNULL(stock_qty, 0) - ISNULL(order_lock_qty, 0) - ISNULL(pick_lock_qty, 0) - ISNULL(lock_qty, 0) < 0
            THEN CAST(0 AS decimal(18, 2))
        ELSE ISNULL(stock_qty, 0) - ISNULL(order_lock_qty, 0) - ISNULL(pick_lock_qty, 0) - ISNULL(lock_qty, 0)
    END AS available_qty
INTO #inv_latest
FROM inv_rank
WHERE rn = 1;

IF OBJECT_ID('tempdb..#ship_base') IS NOT NULL
    DROP TABLE #ship_base;

SELECT
    NULLIF(a.undefined10, '') AS sku_id,
    NULLIF(a.undefined2, '') AS order_id,
    NULLIF(a.undefined12, '') AS product_id,
    NULLIF(a.undefined11, '') AS style_code_from_afs,
    NULLIF(a.undefined96, '') AS product_no_from_afs,
    ISNULL(NULLIF(a.undefined8, ''), 'unknown') AS shop_name,
    CASE
        WHEN CHARINDEX('-', ISNULL(NULLIF(a.undefined8, ''), '')) > 0
            THEN LEFT(ISNULL(NULLIF(a.undefined8, ''), ''), CHARINDEX('-', ISNULL(NULLIF(a.undefined8, ''), '')) - 1)
        ELSE ISNULL(NULLIF(a.undefined8, ''), '未知渠道')
    END AS shop_channel,
    ISNULL(NULLIF(a.undefined66, ''), '') AS ship_warehouse_name,
    COALESCE(
        TRY_CONVERT(datetime2, NULLIF(a.undefined6, ''), 120),
        TRY_CONVERT(datetime2, REPLACE(NULLIF(a.undefined6, ''), '/', '-'), 120),
        TRY_CONVERT(datetime2, NULLIF(a.undefined6, ''), 111),
        TRY_CONVERT(datetime2, a.createdAt)
    ) AS ship_dt,
    COALESCE(
        TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined30, '')),
        TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined20, '')),
        CAST(0 AS decimal(18, 2))
    ) AS shipped_qty
INTO #ship_base
FROM dbo.jst_goods_profit_kpi_items_afs AS a WITH (NOLOCK)
WHERE NULLIF(a.undefined10, '') IN (SELECT sku_id FROM #matched_sku)
  AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%配件%'
  AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%特殊单%';

IF OBJECT_ID('tempdb..#ship_daily') IS NOT NULL
    DROP TABLE #ship_daily;

SELECT
    sb.sku_id,
    CAST(sb.ship_dt AS date) AS ship_date,
    COUNT(DISTINCT sb.order_id) AS order_count,
    SUM(ISNULL(sb.shipped_qty, 0)) AS shipped_qty_sum
INTO #ship_daily
FROM #ship_base AS sb
WHERE sb.ship_dt >= @start_time
  AND sb.ship_dt < @end_time
GROUP BY sb.sku_id, CAST(sb.ship_dt AS date);

IF OBJECT_ID('tempdb..#ship_stats') IS NOT NULL
    DROP TABLE #ship_stats;

SELECT
    sd.sku_id,
    SUM(CASE WHEN sd.ship_date >= CAST(DATEADD(day, -7, @end_time) AS date) THEN ISNULL(sd.shipped_qty_sum, 0) ELSE 0 END) AS shipped_qty_7d,
    SUM(CASE WHEN sd.ship_date >= CAST(DATEADD(day, -30, @end_time) AS date) THEN ISNULL(sd.shipped_qty_sum, 0) ELSE 0 END) AS shipped_qty_30d,
    MAX(sd.ship_date) AS last_ship_date
INTO #ship_stats
FROM #ship_daily AS sd
GROUP BY sd.sku_id;

IF OBJECT_ID('tempdb..#sku_owner') IS NOT NULL
    DROP TABLE #sku_owner;

SELECT
    ms.sku_id,
    COALESCE(
        NULLIF(pc_exact.purchaser, ''),
        NULLIF(pc_style.purchaser, ''),
        NULLIF(pc_base.purchaser, ''),
        '未分配'
    ) AS purchaser_name,
    COALESCE(
        NULLIF(po_exact.oper, ''),
        NULLIF(po_style.oper, ''),
        NULLIF(po_base.oper, ''),
        NULLIF(pc_exact.oper, ''),
        NULLIF(pc_style.oper, ''),
        NULLIF(pc_base.oper, ''),
        '未分配'
    ) AS spu_oper_name
INTO #sku_owner
FROM #matched_sku AS ms
OUTER APPLY (
    SELECT TOP 1 c.purchaser, c.oper
    FROM dbo.fys_SkuDataLibrary_SpuConfig AS c WITH (NOLOCK)
    WHERE NULLIF(c.spu, '') = NULLIF(ms.spu, '')
    ORDER BY c.Id DESC
) AS pc_exact
OUTER APPLY (
    SELECT TOP 1 c.purchaser, c.oper
    FROM dbo.fys_SkuDataLibrary_SpuConfig AS c WITH (NOLOCK)
    WHERE NULLIF(c.spu, '') = NULLIF(ms.style_code, '')
    ORDER BY c.Id DESC
) AS pc_style
OUTER APPLY (
    SELECT TOP 1 c.purchaser, c.oper
    FROM dbo.fys_SkuDataLibrary_SpuConfig AS c WITH (NOLOCK)
    WHERE NULLIF(c.spu, '') = CASE
        WHEN CHARINDEX('K', ISNULL(ms.spu, '')) > 0
            THEN LEFT(ms.spu, CHARINDEX('K', ms.spu) - 1)
        ELSE NULL
    END
    ORDER BY c.Id DESC
) AS pc_base
OUTER APPLY (
    SELECT TOP 1 o.oper
    FROM dbo.op_operManage AS o WITH (NOLOCK)
    WHERE NULLIF(o.spu, '') = NULLIF(ms.spu, '')
    ORDER BY o.Id DESC
) AS po_exact
OUTER APPLY (
    SELECT TOP 1 o.oper
    FROM dbo.op_operManage AS o WITH (NOLOCK)
    WHERE NULLIF(o.spu, '') = NULLIF(ms.style_code, '')
    ORDER BY o.Id DESC
) AS po_style
OUTER APPLY (
    SELECT TOP 1 o.oper
    FROM dbo.op_operManage AS o WITH (NOLOCK)
    WHERE NULLIF(o.spu, '') = CASE
        WHEN CHARINDEX('K', ISNULL(ms.spu, '')) > 0
            THEN LEFT(ms.spu, CHARINDEX('K', ms.spu) - 1)
        ELSE NULL
    END
    ORDER BY o.Id DESC
) AS po_base;

IF OBJECT_ID('tempdb..#tm_oper') IS NOT NULL
    DROP TABLE #tm_oper;

WITH tm_rank AS (
    SELECT
        NULLIF(t.shopproid, '') AS product_id,
        ISNULL(NULLIF(t.shopname, ''), 'unknown') AS shop_name,
        NULLIF(t.oper, '') AS oper_name,
        NULLIF(t.dept, '') AS dept_name,
        ROW_NUMBER() OVER (
            PARTITION BY NULLIF(t.shopproid, ''), ISNULL(NULLIF(t.shopname, ''), 'unknown')
            ORDER BY t.Id DESC
        ) AS rn
    FROM dbo.op_TargetManagement AS t WITH (NOLOCK)
    WHERE NULLIF(t.shopproid, '') IS NOT NULL
)
SELECT
    product_id,
    shop_name,
    oper_name,
    dept_name
INTO #tm_oper
FROM tm_rank
WHERE rn = 1;

IF OBJECT_ID('tempdb..#tm_oper_pid') IS NOT NULL
    DROP TABLE #tm_oper_pid;

SELECT
    product_id,
    MAX(oper_name) AS oper_name,
    MAX(dept_name) AS dept_name
INTO #tm_oper_pid
FROM #tm_oper
GROUP BY product_id;

IF OBJECT_ID('tempdb..#product_id_contact') IS NOT NULL
    DROP TABLE #product_id_contact;

SELECT
    sb.sku_id,
    ms.sku_name,
    ISNULL(NULLIF(sb.product_id, ''), '(未标注)') AS product_id,
    sb.shop_channel,
    sb.shop_name,
    COALESCE(
        NULLIF(tm_shop.oper_name, ''),
        NULLIF(tm_pid.oper_name, ''),
        NULLIF(ow.spu_oper_name, ''),
        '未分配'
    ) AS operator_name,
    COALESCE(NULLIF(ow.purchaser_name, ''), '未分配') AS purchaser_name,
    COALESCE(NULLIF(ms.supplier_name, ''), '未标注') AS factory_name,
    COALESCE(NULLIF(sb.ship_warehouse_name, ''), NULLIF(ms.default_warehouse, ''), NULLIF(inv.inventory_note, ''), '未标注') AS warehouse_name,
    COUNT(DISTINCT sb.order_id) AS order_count_30d,
    SUM(ISNULL(sb.shipped_qty, 0)) AS shipped_qty_sum_30d
INTO #product_id_contact
FROM #ship_base AS sb
INNER JOIN #matched_sku AS ms
    ON ms.sku_id = sb.sku_id
LEFT JOIN #sku_owner AS ow
    ON ow.sku_id = sb.sku_id
LEFT JOIN #tm_oper AS tm_shop
    ON tm_shop.product_id = NULLIF(sb.product_id, '')
   AND tm_shop.shop_name = sb.shop_name
LEFT JOIN #tm_oper_pid AS tm_pid
    ON tm_pid.product_id = NULLIF(sb.product_id, '')
LEFT JOIN #inv_latest AS inv
    ON inv.sku_id = sb.sku_id
WHERE sb.ship_dt >= @start_time
  AND sb.ship_dt < @end_time
  AND ISNULL(NULLIF(sb.product_id, ''), '') <> ''
GROUP BY
    sb.sku_id,
    ms.sku_name,
    ISNULL(NULLIF(sb.product_id, ''), '(未标注)'),
    sb.shop_channel,
    sb.shop_name,
    COALESCE(
        NULLIF(tm_shop.oper_name, ''),
        NULLIF(tm_pid.oper_name, ''),
        NULLIF(ow.spu_oper_name, ''),
        '未分配'
    ),
    COALESCE(NULLIF(ow.purchaser_name, ''), '未分配'),
    COALESCE(NULLIF(ms.supplier_name, ''), '未标注'),
    COALESCE(NULLIF(sb.ship_warehouse_name, ''), NULLIF(ms.default_warehouse, ''), NULLIF(inv.inventory_note, ''), '未标注');

IF OBJECT_ID('tempdb..#risk_eval') IS NOT NULL
    DROP TABLE #risk_eval;

SELECT
    ms.sku_id,
    ms.sku_name,
    inv.stock_qty,
    inv.order_lock_qty,
    inv.pick_lock_qty,
    inv.lock_qty,
    inv.available_qty,
    inv.virtual_qty,
    inv.defective_qty,
    inv.purchase_qty,
    inv.return_qty,
    inv.in_qty,
    inv.min_qty,
    inv.max_qty,
    inv.wms_co_id,
    inv.inventory_snapshot_time,
    ss.last_ship_date,
    CAST(ISNULL(ss.shipped_qty_7d, 0) / 7.0 AS decimal(18, 2)) AS avg_daily_shipped_7d,
    CAST(ISNULL(ss.shipped_qty_30d, 0) / 30.0 AS decimal(18, 2)) AS avg_daily_shipped_30d,
    CAST(
        CASE
            WHEN ISNULL(ss.shipped_qty_30d, 0) <= 0 THEN NULL
            ELSE inv.available_qty / NULLIF(ISNULL(ss.shipped_qty_30d, 0) / 30.0, 0)
        END AS decimal(18, 2)
    ) AS estimated_stockout_days,
    10 AS replenishment_lead_days,
    CAST(
        CASE
            WHEN ISNULL(ss.shipped_qty_30d, 0) <= 0 THEN 0
            WHEN inv.available_qty >= (ISNULL(ss.shipped_qty_30d, 0) / 30.0) * 10 THEN 0
            ELSE ((ISNULL(ss.shipped_qty_30d, 0) / 30.0) * 10) - inv.available_qty
        END AS decimal(18, 2)
    ) AS suggest_replenish_qty_to_10d,
    CASE
        WHEN inv.sku_id IS NULL THEN '无库存快照'
        WHEN ISNULL(ss.shipped_qty_30d, 0) <= 0 THEN '近30天无发货'
        WHEN inv.available_qty <= 0 THEN '缺货/可用库存<=0'
        WHEN (inv.available_qty / NULLIF(ISNULL(ss.shipped_qty_30d, 0) / 30.0, 0)) <= 10 THEN '补货紧急（<=10天）'
        WHEN (inv.available_qty / NULLIF(ISNULL(ss.shipped_qty_30d, 0) / 30.0, 0)) <= 15 THEN '补货预警（10-15天）'
        ELSE '库存安全'
    END AS stock_risk_level,
    CASE
        WHEN inv.sku_id IS NULL THEN 0
        WHEN ISNULL(ss.shipped_qty_30d, 0) <= 0 THEN 0
        WHEN inv.available_qty <= 0 THEN 1
        WHEN (inv.available_qty / NULLIF(ISNULL(ss.shipped_qty_30d, 0) / 30.0, 0)) <= 15 THEN 1
        ELSE 0
    END AS has_stock_risk
INTO #risk_eval
FROM #matched_sku AS ms
LEFT JOIN #inv_latest AS inv
    ON inv.sku_id = ms.sku_id
LEFT JOIN #ship_stats AS ss
    ON ss.sku_id = ms.sku_id;

-- 9) 最近N天每日总发货件数（按SKU）
SELECT TOP (@limit)
    sd.sku_id,
    ms.sku_name,
    sd.ship_date,
    sd.order_count,
    sd.shipped_qty_sum
FROM #ship_daily AS sd
LEFT JOIN #matched_sku AS ms
    ON ms.sku_id = sd.sku_id
ORDER BY sd.ship_date DESC, sd.shipped_qty_sum DESC;

-- 10) 库存风险预估（按SKU，补货安全线=10天）
SELECT TOP (@limit)
    re.sku_id,
    re.sku_name,
    re.stock_qty,
    re.order_lock_qty,
    re.pick_lock_qty,
    re.lock_qty,
    re.available_qty,
    re.virtual_qty,
    re.defective_qty,
    re.purchase_qty,
    re.return_qty,
    re.in_qty,
    re.min_qty,
    re.max_qty,
    re.wms_co_id,
    re.inventory_snapshot_time,
    re.last_ship_date,
    re.avg_daily_shipped_7d,
    re.avg_daily_shipped_30d,
    re.estimated_stockout_days,
    re.replenishment_lead_days,
    re.suggest_replenish_qty_to_10d,
    re.stock_risk_level
FROM #risk_eval AS re
ORDER BY
    CASE
        WHEN re.stock_qty IS NULL THEN 9
        WHEN re.avg_daily_shipped_30d <= 0 THEN 8
        WHEN re.available_qty <= 0 THEN 1
        WHEN re.estimated_stockout_days <= 10 THEN 2
        WHEN re.estimated_stockout_days <= 15 THEN 3
        ELSE 4
    END,
    re.estimated_stockout_days ASC,
    re.sku_id ASC;

-- 11) 近30天在售商品ID数量（按店铺渠道）
SELECT TOP (@limit)
    sb.sku_id,
    ms.sku_name,
    sb.shop_channel,
    COUNT(DISTINCT sb.product_id) AS sold_product_id_count_30d,
    COUNT(DISTINCT sb.shop_name) AS shop_count_30d,
    COUNT(DISTINCT sb.order_id) AS order_count_30d,
    SUM(ISNULL(sb.shipped_qty, 0)) AS shipped_qty_sum_30d
FROM #ship_base AS sb
INNER JOIN #matched_sku AS ms
    ON ms.sku_id = sb.sku_id
WHERE sb.ship_dt >= @start_time
  AND sb.ship_dt < @end_time
  AND ISNULL(NULLIF(sb.product_id, ''), '') <> ''
GROUP BY sb.sku_id, ms.sku_name, sb.shop_channel
ORDER BY sold_product_id_count_30d DESC, shipped_qty_sum_30d DESC, sb.shop_channel ASC;

-- 12) 商品ID对应店铺/渠道/运营人（用于通知）
SELECT TOP (@limit)
    pic.sku_id,
    pic.sku_name,
    pic.product_id,
    pic.shop_channel,
    pic.shop_name,
    pic.operator_name,
    pic.purchaser_name,
    pic.factory_name,
    pic.warehouse_name,
    pic.order_count_30d,
    pic.shipped_qty_sum_30d
FROM #product_id_contact AS pic
ORDER BY pic.shipped_qty_sum_30d DESC, pic.order_count_30d DESC, pic.product_id ASC;

-- 13) 缺货风险通知清单（带采购/工厂/仓库/店铺/运营）
SELECT TOP (@limit)
    re.sku_id,
    re.sku_name,
    re.stock_risk_level,
    re.available_qty,
    re.avg_daily_shipped_30d,
    re.estimated_stockout_days,
    re.suggest_replenish_qty_to_10d,
    pic.product_id,
    pic.shop_channel,
    pic.shop_name,
    pic.operator_name,
    pic.purchaser_name,
    pic.factory_name,
    pic.warehouse_name,
    pic.shipped_qty_sum_30d
FROM #risk_eval AS re
LEFT JOIN #product_id_contact AS pic
    ON pic.sku_id = re.sku_id
WHERE re.has_stock_risk = 1
ORDER BY
    CASE
        WHEN re.available_qty <= 0 THEN 1
        WHEN re.estimated_stockout_days <= 10 THEN 2
        WHEN re.estimated_stockout_days <= 15 THEN 3
        ELSE 9
    END,
    re.estimated_stockout_days ASC,
    pic.shipped_qty_sum_30d DESC;
"""


def main() -> int:
    parser = argparse.ArgumentParser(description="Company product info lookup (SQLServer)")
    parser.add_argument("keyword", help="SKU/SPU/款式/产品名关键词")
    parser.add_argument("--days", type=int, default=30, help="lookback window, default 30")
    parser.add_argument("--limit", type=int, default=20, help="max rows per result set")
    args = parser.parse_args()

    kw = args.keyword.strip()
    if not kw:
        print("keyword is required", file=sys.stderr)
        return 2

    days = max(1, min(args.days, 365))
    limit = max(1, min(args.limit, 100))

    sql = build_sql(kw, days, limit)
    cmd = ["company-db", "query", "--sql", sql]
    proc = subprocess.run(cmd, capture_output=True, text=True)
    if proc.returncode != 0:
        err = (proc.stderr or proc.stdout or "company-db failed").strip()
        print(err, file=sys.stderr)
        return proc.returncode

    print(proc.stdout.rstrip())
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
