# -*- coding: utf-8 -*-
"""Gantt-style timeline for 3D OpticsFEM (target: late July 2026)."""
from __future__ import annotations

from datetime import date, timedelta
from pathlib import Path

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.patches as mpatches

OUT = Path(__file__).resolve().parent

plt.rcParams["font.sans-serif"] = ["Microsoft YaHei", "SimHei", "Arial"]
plt.rcParams["axes.unicode_minus"] = False

GREEN = "#75BD42"
GREEN_D = "#4A7C3F"
BLUE = "#4874CB"
ORANGE = "#EE822F"
GRAY = "#CCCCCC"
DARK = "#2C3E50"
WHITE = "#FFFFFF"

# (label, start, end, color, status)
# status: done | doing | plan | stretch
T0 = date(2026, 6, 1)
ITEMS = [
    ("阶段0 工程基础", date(2026, 6, 1), date(2026, 6, 15), GREEN, "done"),
    ("阶段2 PEC/ELE", date(2026, 6, 10), date(2026, 6, 20), GREEN, "done"),
    ("阶段3 PBC 单/双周期", date(2026, 6, 15), date(2026, 6, 25), GREEN, "done"),
    ("阶段1 本征频率 Run/Post", date(2026, 6, 23), date(2026, 7, 5), ORANGE, "doing"),
    ("阶段4 BELE/源项边界", date(2026, 6, 28), date(2026, 7, 12), BLUE, "plan"),
    ("算例验证 & 文档整理", date(2026, 7, 8), date(2026, 7, 18), BLUE, "plan"),
    (".em 接口适配（基础）", date(2026, 7, 10), date(2026, 7, 25), BLUE, "plan"),
    ("阶段5 PML/Port（可选）", date(2026, 7, 20), date(2026, 8, 10), GRAY, "stretch"),
    ("阶段6 本征模式/二阶（可选）", date(2026, 8, 1), date(2026, 8, 31), GRAY, "stretch"),
]

MILESTONES = [
    (date(2026, 6, 25), "阶段1–3\n验收"),
    (date(2026, 7, 18), "MVP\n内测"),
    (date(2026, 7, 31), "7月下旬\n交付"),
]


def main() -> None:
    fig, ax = plt.subplots(figsize=(14, 6.2), facecolor=WHITE)

    y = len(ITEMS)
    for i, (label, start, end, color, status) in enumerate(ITEMS):
        yy = y - i
        width = (end - start).days + 1
        hatch = "" if status != "stretch" else "///"
        alpha = 1.0 if status != "stretch" else 0.55
        ax.barh(
            yy, width, left=mdates.date2num(start), height=0.55,
            color=color, edgecolor=DARK, linewidth=0.8,
            hatch=hatch, alpha=alpha,
        )
        mid = start + timedelta(days=width // 2)
        ax.text(
            mdates.date2num(mid), yy, label,
            ha="center", va="center", fontsize=9.5,
            color=WHITE if status in ("done", "doing") else DARK,
            fontweight="bold" if status == "doing" else "normal",
        )

    for ms_date, ms_text in MILESTONES:
        x = mdates.date2num(ms_date)
        ax.axvline(x, color="#C0392B", ls="--", lw=1.2, alpha=0.75, zorder=0)
        ax.text(x, y + 0.55, ms_text, ha="center", va="bottom", fontsize=8.5,
                color="#C0392B", fontweight="bold")

    ax.set_yticks([])
    ax.set_ylim(0.3, y + 1.2)
    ax.set_xlim(mdates.date2num(date(2026, 5, 28)), mdates.date2num(date(2026, 9, 5)))
    ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MO, interval=1))
    ax.xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
    ax.xaxis.set_minor_locator(mdates.DayLocator(interval=1))
    ax.grid(axis="x", alpha=0.25, ls="--")
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["left"].set_visible(False)

    ax.set_title(
        "OpticsFEM 3D 扩展 — 时间节点规划（目标：2026年7月下旬交付）",
        fontsize=14, fontweight="bold", color=DARK, pad=14,
    )

    legend_items = [
        mpatches.Patch(facecolor=GREEN, edgecolor=DARK, label="已完成"),
        mpatches.Patch(facecolor=ORANGE, edgecolor=DARK, label="进行中"),
        mpatches.Patch(facecolor=BLUE, edgecolor=DARK, label="7月计划"),
        mpatches.Patch(facecolor=GRAY, edgecolor=DARK, hatch="///", alpha=0.55, label="8月及以后（扩展）"),
    ]
    ax.legend(handles=legend_items, loc="lower right", fontsize=9, framealpha=0.95)

    out = OUT / "timeline_july2026.png"
    fig.savefig(out, dpi=180, bbox_inches="tight", facecolor=WHITE)
    plt.close(fig)
    print(f"Saved {out}")


if __name__ == "__main__":
    main()
