import { useComputed, type Signal } from "@preact/signals";
import { addplan, bplan, IPlan, Plan, storage_keys } from "../common/plan.ts";
import { datefmt, datefrom } from "../common/date.ts";

export interface CalendarProps {
    date: Signal<number>;
    plans: Signal<Plan[]>;
}

const casht_a = -800;
const casht_b = -950;

const calendar_span = 30;

const calendar_days = new Array(calendar_span).fill(0).map((_, i) => i);

export default function Calendar({ date, plans }: CalendarProps) {
    const _calendar = useComputed(() => {
        // cal
        let e: number[] = [];
        const cal: Record<number, IPlan[]> = {};
        for (const p of plans.value) {
            e = e.concat(addplan(cal, p));
        }
        e = Array.from(new Set(e)).sort((a, b) => a - b);
        let c = 600;
        let current = 600;
        let alert = -1;
        let die = -1;
        /*
        const cal_ex: Record<number, IPlan[]> = {};
        const e_ex: number[] = [];
        */
        // cash
        for (const d of e) {
            for (const p of cal[d]) {
                c -= p.cost;
                p.current = c;
                if (alert === -1 && c < casht_a && d < datefrom(6, 1, 1))
                    alert = d;
                if (die === -1 && c < casht_b && d < datefrom(6, 1, 1))
                    die = d;
                /*
                if (c < 0) {
                    e_ex.push(...(addplan(cal_ex, bplan({
                        name: "借款",
                        start: d,
                        price: -p.cost,
                    })).concat(addplan(cal_ex, bplan({
                        name: "还贷",
                        start: d + 360,
                        price: p.cost * 1.05,
                    })))));
                }
                */
            }
            if (d < date.value + 30) {
                current = c;
            }
        }
        /*
        for (const k in cal_ex) {
            if (cal[k])
                cal[k].push(...cal_ex[k]);
            else
                cal[k] = cal_ex[k];
        }
        e.push(...e_ex);
        */
        return {
            cal: cal,
            e: e,
            cash: current,
            alert: alert,
            die: die,
        };
    });
    const calendar = useComputed(() => _calendar.value.cal);
    const event_days = useComputed(() => _calendar.value.e);
    const cash = useComputed(() => _calendar.value.cash);
    const date_alert = useComputed(() => _calendar.value.alert);
    const date_die = useComputed(() => _calendar.value.die);
    const storage = useComputed(() => {
        const st: Record<string, number> = {};
        for (const d of event_days.value) {
            if (d >= date.value + 30)
                break;
            for (const p of calendar.value[d]) {
                if (!p.plan.role) continue;
                for (let role of p.plan.role.split(",")) {
                    let amount = p.plan.amount;
                    // if (!role) continue;
                    if (role[0] === "-") {
                        amount = -amount;
                        role = role.slice(1);
                    }
                    if (st[role] === undefined)
                        st[role] = 0;
                    st[role] += amount;
                }
            }
        }
        return st;
    });
    let last_date = -1;
    return <div class="calendar">
            <div class="calendar__calendar">
            <div class="calender__cash">￥{cash.value}</div>
            <div class="calendar__head">
                <button onClick={() => date.value -= 360}>&lt;&lt;&lt;</button>
                <button onClick={() => date.value -= 90}>&lt;&lt;</button>
                <button onClick={() => date.value -= 30}>&lt;</button>
                <span class="calendar__date">{datefmt(date.value)}</span>
                <button onClick={() => date.value += 30}>&gt;</button>
                <button onClick={() => date.value += 90}>&gt;&gt;</button>
                <button onClick={() => date.value += 360}>&gt;&gt;&gt;</button>
            </div>
            <div class="calendar__days">
                {calendar_days.map(d => <span class={calendar.value[d + date.value] ? "p" : ""}>{d + 1}</span>)}
            </div>
        </div>
        <div class="calendar__alert" hidden>
            <p>{date_alert.value === -1 ? "" : "资金周转风险 (现金 < " + casht_a + "): " + datefmt(date_alert.value)}</p>
            <p>{date_die.value === -1 ? "" : "资金链断裂 (现金 < " + casht_b + "): " + datefmt(date_die.value)}</p>
        </div>
        <table class="calendar__storage">
            <thead>
                <tr><td>库存</td><td>数量</td></tr>
            </thead>
            <tbody>
                {Object.entries(storage.value).filter(st => storage_keys[st[0]] && st[1]).map(st => <tr><td>{storage_keys[st[0]]}</td><td>{st[1]}</td></tr>)}
            </tbody>
        </table>
        <table class="calendar__events" cellSpacing="0">
            <thead>
                <tr>
                    <td>日期</td>
                    <td>描述</td>
                    <td>数量</td>
                    <td>次序</td>
                    <td>收支</td>
                    <td>余额</td>
                </tr>
            </thead>
            <tbody>
            {calendar_days.map(d => d + date.value).filter(d => calendar.value[d]).map(d => calendar.value[d].map(p => {
                const e = <tr>
                    <td>{last_date === p.date ? "" : datefmt(p.date)}</td>
                    <td>{p.plan.name}</td>
                    <td>{p.plan.amount}</td>
                    <td>{p.plan.times === 1 ? "1" : "" + (p.order + 1) + " / " + p.plan.times}</td>
                    <td>{p.cost !== 0 ? "￥" + (-p.cost) : ""}</td>
                    <td>￥{p.current}</td>
                </tr>
                last_date = p.date;
                return e;
            }))}
            </tbody>
        </table>
    </div>;
}
