/**
 * GanttSection.js — نمودار گانت ساده (CSS-based)
 */
import SectionBase from "../../accounting/SectionBase.js";

const STATUS_COLOR = {
    not_started: "#94a3b8",
    in_progress:  "#3b82f6",
    completed:    "#22c55e",
    on_hold:      "#f59e0b",
    cancelled:    "#ef4444",
};

export default class GanttSection extends SectionBase {

    constructor(props = {}) {
        super(props);
        this.cpmView    = props.cpmView ?? null;
        this._projectId = null;
        this._tasks     = [];
        this._wbs       = [];
        this._project   = null;
    }

    async template() {
        return `
            <div class="cpm-section-wrap">
                <div class="cpm-section-notice" data-ref="notice">
                    <span>⚠️ لطفاً ابتدا یک پروژه از تب «پروژه‌ها» انتخاب کنید.</span>
                </div>
                <div data-ref="content" style="display:none">
                    <div class="cpm-toolbar">
                        <span data-ref="projLabel" style="font-weight:700;color:#1e293b;font-size:14px;"></span>
                        <button class="acc-btn acc-btn--primary acc-btn--sm" data-ref="calcCpmBtn">⚡ محاسبه CPM</button>
                        <button class="acc-btn acc-btn--secondary acc-btn--sm" data-ref="refreshBtn">🔄 بروزرسانی</button>
                    </div>
                    <div class="cpm-gantt-legend">
                        <span class="cpm-gantt-legend-item" style="--clr:#94a3b8">شروع نشده</span>
                        <span class="cpm-gantt-legend-item" style="--clr:#3b82f6">در حال انجام</span>
                        <span class="cpm-gantt-legend-item" style="--clr:#22c55e">تکمیل</span>
                        <span class="cpm-gantt-legend-item" style="--clr:#f59e0b">متوقف</span>
                        <span class="cpm-gantt-legend-item" style="--clr:#ef4444">لغو</span>
                        <span class="cpm-gantt-legend-item cpm-gantt-legend-item--critical" style="--clr:#dc2626">🔴 بحرانی</span>
                    </div>
                    <div class="cpm-gantt-wrap" data-ref="ganttWrap"></div>
                </div>
            </div>
        `;
    }

    async afterRender() {
        // notice shown by default
    }

    async onProjectChange(project) {
        this._projectId = project?.id ?? null;
        this._project   = project;
        if (!this._projectId) {
            this.ref("notice").style.display = "flex";
            this.ref("content").style.display = "none";
            return;
        }
        this.ref("notice").style.display = "none";
        this.ref("content").style.display = "block";
        if (project?.name) {
            this.ref("projLabel").textContent = `🏗 ${project.name}`;
        }
        this.on(this.ref("calcCpmBtn"), "click", () => this._calculateCpm());
        this.on(this.ref("refreshBtn"), "click", () => this._loadAndRender());
        await this._loadAndRender();
    }

    async _loadAndRender() {
        const wrap = this.ref("ganttWrap");
        wrap.innerHTML = `<div class="cpm-loading" style="padding:40px 0"><div class="acc-spinner"></div></div>`;
        try {
            const res = await this.api.get(`/pc/projects/${this._projectId}/workspace`, { scope: "gantt" });
            this._wbs     = res?.wbs     ?? [];
            this._tasks   = res?.tasks   ?? [];
            if (res?.project) this._project = res.project;
            this._renderGantt(wrap);
        } catch {
            wrap.innerHTML = `<div class="acc-empty">خطا در بارگذاری داده‌های گانت</div>`;
        }
    }

    async _calculateCpm() {
        const btn = this.ref("calcCpmBtn");
        btn.disabled = true;
        btn.textContent = "⏳ در حال محاسبه...";
        try {
            const res = await this.api.post(`/pc/projects/${this._projectId}/calculate-cpm`);
            if (res?.success) {
                const n = res.count ?? 0;
                btn.textContent = `✅ ${n} وظیفه محاسبه شد`;
                setTimeout(() => {
                    btn.disabled = false;
                    btn.textContent = "⚡ محاسبه CPM";
                }, 2500);
                await this._loadAndRender();
            } else {
                throw new Error(res?.message ?? "خطای نامشخص");
            }
        } catch (err) {
            alert("خطا در محاسبه CPM: " + (err?.message ?? ""));
            btn.disabled = false;
            btn.textContent = "⚡ محاسبه CPM";
        }
    }

    _renderGantt(wrap) {
        // prefer CPM early dates if available, fall back to planned dates
        const tasks = this._tasks.filter(t =>
            (t.early_start || t.start_date) && (t.early_finish || t.end_date)
        );
        if (!tasks.length) {
            wrap.innerHTML = `<div class="acc-empty">وظیفه‌ای با تاریخ یافت نشد.<br>
                <small style="color:#94a3b8">برای نمایش گانت، ابتدا روی «⚡ محاسبه CPM» کلیک کنید یا تاریخ وظایف را تنظیم کنید.</small></div>`;
            return;
        }

        // Determine overall date range (prefer early_start/early_finish)
        const allDates = tasks.flatMap(t => [
            new Date(t.early_start || t.start_date),
            new Date(t.early_finish || t.end_date),
        ]);
        let minDate = new Date(Math.min(...allDates));
        let maxDate = new Date(Math.max(...allDates));

        // Expand a bit
        minDate.setDate(minDate.getDate() - 2);
        maxDate.setDate(maxDate.getDate() + 2);

        const totalDays = Math.ceil((maxDate - minDate) / 86400000) || 1;

        // Build WBS name map
        const wbsMap = {};
        this._wbs.forEach(w => { wbsMap[w.id] = w.name; });

        // Build header weeks
        const weekHeaders = this._buildWeekHeaders(minDate, totalDays);

        // Sort tasks by start_date then sort_index
        const sorted = [...tasks].sort((a, b) => {
            const da = new Date(a.early_start || a.start_date);
            const db = new Date(b.early_start || b.start_date);
            return da - db || (a.sort_index - b.sort_index);
        });

        const rows = sorted.map(t => {
            const tStart = t.early_start || t.start_date;
            const tEnd   = t.early_finish || t.end_date;
            const start = Math.max(0, Math.ceil((new Date(tStart) - minDate) / 86400000));
            const end   = Math.ceil((new Date(tEnd) - minDate) / 86400000);
            const dur   = Math.max(1, end - start);
            const left  = (start / totalDays * 100).toFixed(3);
            const width = (dur   / totalDays * 100).toFixed(3);
            const color = t.is_critical ? "#dc2626" : (STATUS_COLOR[t.status] ?? "#94a3b8");
            const pct   = parseFloat(t.progress ?? 0).toFixed(0);
            const wbsName = wbsMap[t.wbs_id] ? `<span class="cpm-gantt-wbs">${this.escape(wbsMap[t.wbs_id])}</span>` : "";

            return `
                <div class="cpm-gantt-row${t.is_critical ? " cpm-gantt-row--critical" : ""}">
                    <div class="cpm-gantt-row__label" title="${this.escape(t.name)}">
                        ${wbsName}
                        <span class="cpm-gantt-task-name">${this.escape(t.name)}</span>
                    </div>
                    <div class="cpm-gantt-row__track">
                        <div class="cpm-gantt-bar" style="left:${left}%;width:${width}%;background:${color};"
                             title="${this.escape(t.name)} | ${tStart} → ${tEnd} | ${pct}٪">
                            <div class="cpm-gantt-bar__fill" style="width:${pct}%"></div>
                            <span class="cpm-gantt-bar__label">${pct}٪</span>
                        </div>
                    </div>
                </div>
            `;
        }).join("");

        wrap.innerHTML = `
            <div class="cpm-gantt-table">
                <div class="cpm-gantt-header">
                    <div class="cpm-gantt-header__label">وظیفه</div>
                    <div class="cpm-gantt-header__track">
                        ${weekHeaders}
                    </div>
                </div>
                <div class="cpm-gantt-body">${rows}</div>
            </div>
            <div class="cpm-gantt-range-info">
                📅 بازه: ${minDate.toISOString().slice(0,10)} تا ${maxDate.toISOString().slice(0,10)}
                &nbsp;|&nbsp; ${totalDays} روز &nbsp;|&nbsp; ${sorted.length} وظیفه
                &nbsp;|&nbsp; 🔴 بحرانی: ${sorted.filter(t => t.is_critical).length}
            </div>
        `;
    }

    _buildWeekHeaders(minDate, totalDays) {
        const items = [];
        let cur = new Date(minDate);
        cur.setDate(cur.getDate() - cur.getDay()); // align to week start

        while (cur <= new Date(minDate.getTime() + totalDays * 86400000)) {
            const wStart = new Date(cur);
            const wEnd   = new Date(cur); wEnd.setDate(wEnd.getDate() + 6);
            const leftDays = Math.max(0, (wStart - minDate) / 86400000);
            const left = (leftDays / totalDays * 100).toFixed(2);
            items.push(
                `<div class="cpm-gantt-week" style="left:${left}%">
                    ${wStart.toISOString().slice(5,10)}
                 </div>`
            );
            cur.setDate(cur.getDate() + 7);
            if (items.length > 60) break; // safety
        }
        return items.join("");
    }
}
