# Generate VTeam DD Gantt chart HTML

items = [
    # (id, short_name, category, start_ym, recurrence, next_deadline, status, notes)
    (1,  'WhiteList 331 買家/賣家資訊核對', 'ad_hoc', '2026-08', 'ad_hoc', '待交易前', 'ongoing', '部分尚缺，待交易前補實'),
    (2,  '59個新買家完整資訊', 'ad_hoc', '2026-08', 'ad_hoc', '待交易前', 'ongoing', '部分尚缺，待交易前補實'),
    (3,  '發票號碼不重複驗證系統', 'permanent', '2026-08', 'permanent', '永久', 'in_progress', 'AI Agent 已監控；違規→賣回/換單'),
    (4,  '回款通知電郵加入基金密件副本', 'ad_hoc', '2026-08', 'ad_hoc', '待確認', 'pending', '仍在討論；目前每月抽樣驗證'),
    (5,  '年度徵信報告更新', 'annual_jan', '2027-01', 'yearly', '2027-01', 'scheduled', '每年1月第一週更新'),
    (6,  'UBO更新制度', 'semi_annual', '2026-12', '6months', '2027-01', 'scheduled', '格式2026-12提供；首次2027-01；之後每半年'),
    (7,  'SCP6-2 日本買家占比13-18%', 'monthly', '2026-08', 'monthly', '每月中旬', 'in_progress', '每月中旬前確認當月換單安排'),
    (8,  '新基金買家占比機制（43 BBB-）', 'ad_hoc', '2026-08', 'ad_hoc', '待通知', 'pending', '與管理機構討論中'),
    (9,  'WeChat/電郵溝通回應改善', 'permanent', '2026-08', 'permanent', '永久', 'pending', '狀況仍不佳；請改善'),
    (10, 'Q1年報：逾期率及客戶地點', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末提供上年資訊'),
    (11, 'Q1年報：信用風險/商業糾紛統計', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末'),
    (12, 'Q1年報：扣款率>8-10%買家清單', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末'),
    (13, 'Q1年報：逾期>14天計息買家', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末'),
    (14, 'Q1年報：逾期>28天取消額度買家', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末'),
    (15, 'Q1年報：申請回款展期買家', 'annual_q1', '2027-03', 'yearly', '2027-03-31', 'scheduled', '每年Q1末'),
    (16, '半年度 WhiteList 核對', 'semi_annual', '2027-01', '6months', '2027-01', 'scheduled', '基金提供→VTeam審核→1月末回覆'),
    (17, 'NTR與基金交易紀錄對接研究', 'ad_hoc', '2026-08', 'ad_hoc', '研究中', 'pending', '建議提供非OCR PDF + xlsx格式NTR'),
]

STATUS_COLOR = {
    'in_progress': '#2ecc71',
    'ongoing': '#3498db',
    'pending': '#e67e22',
    'scheduled': '#9b59b6',
    'completed': '#95a5a6',
}
STATUS_LABEL = {
    'in_progress': '進行中',
    'ongoing': '持續執行',
    'pending': '待處理',
    'scheduled': '已排程',
    'completed': '已完成',
}
CAT_COLOR = {
    'permanent': '#16a085',
    'monthly': '#2980b9',
    'ad_hoc': '#7f8c8d',
    'semi_annual': '#8e44ad',
    'annual_jan': '#c0392b',
    'annual_q1': '#d35400',
}
CAT_LABEL = {
    'permanent': '永久監控',
    'monthly': '每月',
    'ad_hoc': '不定期',
    'semi_annual': '每半年',
    'annual_jan': '每年1月',
    'annual_q1': '每年Q1末',
}

# Timeline: 2026-H2 + 2027 full year
MONTHS = [
    ('2026-08','Aug'), ('2026-09','Sep'), ('2026-10','Oct'), ('2026-11','Nov'), ('2026-12','Dec'),
    ('2026','─── 2026 ───'), 
    ('2027-01','Jan'), ('2027-02','Feb'), ('2027-03','Mar'), ('2027-04','Apr'),
    ('2027-05','May'), ('2027-06','Jun'), ('2027-07','Jul'), ('2027-08','Aug'),
    ('2027-09','Sep'), ('2027-10','Oct'), ('2027-11','Nov'), ('2027-12','Dec'),
    ('2027','─── 2027 ───'),
]

# Generate the bar positions for each item in the timeline
def get_bars(item):
    id_, name, cat, start, recur, deadline, status, note = item
    bars = []
    if cat == 'permanent' or cat == 'ad_hoc' and recur == 'permanent':
        # Full bar across all months
        bars.append({'months': ['2026-08','2026-09','2026-10','2026-11','2026-12',
                                 '2027-01','2027-02','2027-03','2027-04','2027-05',
                                 '2027-06','2027-07','2027-08','2027-09','2027-10','2027-11','2027-12'],
                     'type': 'continuous'})
    elif recur == 'monthly':
        bars.append({'months': ['2026-08','2026-09','2026-10','2026-11','2026-12',
                                 '2027-01','2027-02','2027-03','2027-04','2027-05',
                                 '2027-06','2027-07','2027-08','2027-09','2027-10','2027-11','2027-12'],
                     'type': 'monthly'})
    elif recur == 'ad_hoc':
        bars.append({'months': [start] if start in ['2026-08','2026-09'] else [],
                     'type': 'milestone'})
    elif recur == '6months':
        # Semi-annual: Jan, Jul pattern or Dec→Jul
        m = ['2026-12','2027-01','2027-07']
        bars.append({'months': [x for x in m if x in [
            '2026-08','2026-09','2026-10','2026-11','2026-12',
            '2027-01','2027-02','2027-03','2027-04','2027-05',
            '2027-06','2027-07','2027-08','2027-09','2027-10','2027-11','2027-12']],
            'type': 'milestone'})
    elif recur == 'yearly' and cat == 'annual_jan':
        bars.append({'months': ['2027-01'], 'type': 'milestone'})
    elif recur == 'yearly' and cat == 'annual_q1':
        bars.append({'months': ['2027-01','2027-02','2027-03'], 'type': 'continuous'})
    return bars

html = '''<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>260814-17 DD VTeam 後持續工作清單</title>
<style>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:'Microsoft JhengHei','Calibri',sans-serif;background:#f0f4f8;color:#222;padding:16px;}
h1{font-size:22px;color:#1a3c6e;margin-bottom:4px;font-weight:900;}
.subtitle{font-size:13px;color:#888;margin-bottom:16px;}
.legend{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:16px;padding:10px 14px;background:#fff;border-radius:6px;border:1px solid #ddd;}
.leg-item{display:flex;align-items:center;gap:6px;font-size:13px;}
.leg-dot{width:14px;height:14px;border-radius:3px;}
table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.08);}
thead th{background:#1a3c6e;color:#fff;padding:9px 8px;font-size:13px;text-align:center;white-space:nowrap;}
thead th.item-col{text-align:left;min-width:220px;}
tbody tr:nth-child(even){background:#f9fbff;}
tbody tr:hover{background:#eef4ff;}
td{padding:8px;font-size:13px;border-bottom:1px solid #e8ecf2;vertical-align:middle;}
td.id-col{text-align:center;font-weight:bold;width:38px;color:#1a3c6e;}
td.name-col{min-width:220px;line-height:1.4;}
td.cat-col{text-align:center;width:70px;}
td.month-col{width:46px;text-align:center;}
.bar-cont{background:#3498db;border-radius:3px;height:18px;width:100%;opacity:0.85;}
.bar-month{background:#2980b9;border-radius:3px;height:18px;width:80%;margin:0 auto;opacity:0.7;}
.bar-milestone{display:flex;justify-content:center;align-items:center;}
.diamond{width:16px;height:16px;transform:rotate(45deg);border-radius:2px;}
.cat-badge{display:inline-block;padding:2px 7px;border-radius:10px;font-size:11px;color:#fff;white-space:nowrap;}
.status-badge{display:inline-block;padding:2px 7px;border-radius:10px;font-size:11px;color:#fff;}
.section-row td{background:#e8ecf2;font-weight:bold;font-size:12px;color:#555;padding:5px 8px;}
.note-row td{font-size:11px;color:#888;padding:3px 8px 7px;border-bottom:2px solid #d0d8e8;}
</style>
</head>
<body>
<h1>260814-17 DD VTeam 後持續工作清單</h1>
<div class="subtitle">依據 2026-08-04~07 重慶/武漢 Due Diligence 後 17 項持續工作清單 | 甘特圖 | 匯出：2026-10-05</div>

<div class="legend">
'''

for s, c in STATUS_COLOR.items():
    html += f'<div class="leg-item"><div class="leg-dot" style="background:{c}"></div>{STATUS_LABEL[s]}</div>\n'

html += '<span style="color:#ccc;margin:0 8px">|</span>'
for c, col in CAT_COLOR.items():
    html += f'<div class="leg-item"><div class="leg-dot" style="background:{col}"></div>{CAT_LABEL[c]}</div>\n'

html += '</div>\n'

# Timeline columns
timeline_cols = [
    '2026-08','2026-09','2026-10','2026-11','2026-12',
    '2027-01','2027-02','2027-03','2027-04','2027-05',
    '2027-06','2027-07','2027-08','2027-09','2027-10','2027-11','2027-12'
]
month_labels = {
    '2026-08':'8月','2026-09':'9月','2026-10':'10月','2026-11':'11月','2026-12':'12月',
    '2027-01':'1月','2027-02':'2月','2027-03':'3月','2027-04':'4月','2027-05':'5月',
    '2027-06':'6月','2027-07':'7月','2027-08':'8月','2027-09':'9月','2027-10':'10月','2027-11':'11月','2027-12':'12月',
}

html += '<table>\n<thead><tr>'
html += '<th class="item-col" style="text-align:center;">序</th>'
html += '<th class="item-col">工作項目</th>'
html += '<th>週期</th>'
html += '<th colspan="5" style="border-right:2px solid #3a6bbf;">2026</th>'
html += '<th colspan="12">─────────────────── 2027 ───────────────────</th>'
html += '</tr><tr>'
html += '<th></th><th></th><th></th>'
for m in timeline_cols:
    html += f'<th>{month_labels[m]}</th>'
html += '</tr></thead>\n<tbody>\n'

# Group items by category
cat_order = ['permanent','monthly','ad_hoc','semi_annual','annual_jan','annual_q1']
cat_groups = {}
for item in items:
    cat = item[2]
    if cat not in cat_groups: cat_groups[cat] = []
    cat_groups[cat].append(item)

for cat in cat_order:
    if cat not in cat_groups: continue
    # Section header
    html += f'<tr class="section-row"><td colspan="{3+len(timeline_cols)}">{CAT_LABEL[cat]}</td></tr>\n'
    
    for item in cat_groups[cat]:
        id_, name, cat_, start, recur, deadline, status, note = item
        s_color = STATUS_COLOR[status]
        cat_color = CAT_COLOR[cat_]
        bars = get_bars(item)
        bar_months = set()
        bar_type = 'none'
        for b in bars:
            bar_months.update(b['months'])
            bar_type = b['type']
        
        html += '<tr>'
        html += f'<td class="id-col">{id_}</td>'
        html += f'<td class="name-col"><span class="status-badge" style="background:{s_color}">{STATUS_LABEL[status]}</span> {name}</td>'
        html += f'<td class="cat-col"><span class="cat-badge" style="background:{cat_color}">{CAT_LABEL[cat_]}</span></td>'
        
        for m in timeline_cols:
            if m in bar_months:
                if bar_type == 'continuous':
                    html += f'<td class="month-col"><div class="bar-cont" style="background:{s_color}"></div></td>'
                elif bar_type == 'monthly':
                    html += f'<td class="month-col"><div class="bar-month" style="background:{s_color}"></div></td>'
                else:  # milestone
                    html += f'<td class="month-col"><div class="bar-milestone"><div class="diamond" style="background:{s_color}"></div></div></td>'
            else:
                # Check if current month is a "monitoring" month for certain items
                if bar_type == 'continuous' and m >= start and m <= '2027-12':
                    html += f'<td class="month-col"><div style="background:{s_color};opacity:.15;height:4px;width:100%;margin:7px 0;border-radius:2px;"></div></td>'
                else:
                    html += '<td class="month-col"></td>'
        
        html += '</tr>\n'
        # Note row
        html += f'<tr class="note-row"><td></td><td colspan="{2+len(timeline_cols)}">{note}</td></tr>\n'

html += '</tbody></table>\n'
html += f'''<div style="margin-top:12px;font-size:12px;color:#aaa;text-align:right;">
下一個關鍵截止日：<strong>2026-12</strong> UBO格式提供 / <strong>2027-01</strong> 半年度WhiteList核對 + UBO首次更新 + 徵信報告 / <strong>2027-03-31</strong> Q1年報（項目10-15）
</div>
</body></html>'''

with open('/tmp/vteam_dd_gantt.html', 'w', encoding='utf-8') as f:
    f.write(html)
print(f"Gantt chart created: {len(html)} chars")
