import { router, usePage } from "@inertiajs/react";
import { useState } from "react";
import Shell from "../components/Shell";
import { currentSchoolYear, periodName, schoolYears } from "../school-periods";
import MeetingEditor, { days } from "../components/MeetingEditor";
import {
    Badge,
    Empty,
    Field,
    Heading,
    Panel,
    SaveForm,
} from "../components/ui";
import type { Course, Meeting, Period, Shared } from "../types";

export default function Schedule({
    courses,
    options,
    can_manage,
    period,
    school_year,
}: {
    courses: Course[];
    options: { periods: Period[] };
    can_manage: boolean;
    period: string;
    school_year: string;
}) {
    const { auth, permissions } = usePage<Shared>().props;
    const personal =
        auth?.user_type === "student" ||
        (permissions.includes("class.teach") &&
            !permissions.includes("class.read"));
    const [edits, setEdits] = useState<Record<number, Meeting[]>>({});
    const changes = Object.entries(edits).map(([id, meetings]) => ({
        class_id: Number(id),
        meetings,
    }));
    const year =
        school_year ||
        options.periods.find((p) => String(p.id) === period)?.school_year ||
        currentSchoolYear(options.periods);
    const filter = (
        <div className="form-grid">
            <Field label="School year">
                <select
                    value={year}
                    onChange={(event) =>
                        router.get("/schedule", {
                            school_year: event.target.value,
                            period: "0",
                        })
                    }
                >
                    {schoolYears(options.periods).map((year) => (
                        <option key={year} value={year}>
                            {year}
                        </option>
                    ))}
                </select>
            </Field>
            <Field label="Enrollment period">
                <select
                    value={period}
                    onChange={(e) =>
                        router.get(
                            "/schedule",
                            e.target.value === "current"
                                ? {}
                                : { period: e.target.value, school_year: year },
                        )
                    }
                >
                    <option value="current">
                        Current semester / school year
                    </option>
                    <option value="0">All semesters / school levels</option>
                    {options.periods
                        .filter((p) => p.school_year === year)
                        .map((p) => (
                            <option key={p.id} value={p.id}>
                                {periodName(p)}
                            </option>
                        ))}
                </select>
            </Field>
        </div>
    );
    return (
        <Shell title={personal ? "My schedule" : "Class schedules"}>
            <Heading
                title={personal ? "My schedule" : "Class schedules"}
                description={
                    can_manage
                        ? "Maintain weekly meeting times. Rescheduling checks every affected Student and Teacher and preserves issued CORs."
                        : personal
                          ? "Your assigned or enrolled classes and their current weekly meeting times."
                          : "View subject classes, Teachers and weekly meeting times by school year and semester."
                }
            />
            <Panel>{filter}</Panel>
            {!courses.length && (
                <Panel>
                    <Empty title="No classes in this period">
                        Choose another period or ask the School Administrator to
                        review class assignments.
                    </Empty>
                </Panel>
            )}
            {can_manage ? (
                <SaveForm
                    url="/schedule"
                    method="put"
                    label="Save meeting times"
                    reset={false}
                    disabled={!changes.length}
                    onSuccess={() => setEdits({})}
                >
                    <input
                        type="hidden"
                        name="changes"
                        value={JSON.stringify(changes)}
                    />
                    {courses.map((c) => (
                        <Panel
                            key={c.id}
                            title={`${c.subject.code} · ${c.section}`}
                        >
                            <p>
                                {c.subject.name} · {c.teacher.name} ·{" "}
                                {c.branch.name}
                            </p>
                            <p className="small">
                                {c.period.name} · Usual Sections:{" "}
                                {c.sections?.map((s) => s.name).join(", ") ||
                                    "Not linked"}
                            </p>
                            {c.finalized_at ? (
                                <>
                                    <Badge tone="success">
                                        Final grades finalized
                                    </Badge>
                                    <p>{c.schedule}</p>
                                </>
                            ) : (
                                <>
                                    <MeetingEditor
                                        required={!!edits[c.id]}
                                        value={
                                            edits[c.id] ??
                                            c.meetings ?? [
                                                { day: 1, start: "", end: "" },
                                            ]
                                        }
                                        onChange={(meetings) =>
                                            setEdits({
                                                ...edits,
                                                [c.id]: meetings,
                                            })
                                        }
                                    />
                                    {!c.meetings?.length && (
                                        <p className="small">
                                            Existing meeting times need review.
                                            Include other unreviewed assignments
                                            in this save when they affect the
                                            same Teacher or Students.
                                        </p>
                                    )}
                                </>
                            )}
                        </Panel>
                    ))}
                    <Panel title="Reason for timetable changes">
                        <Field label="Reason">
                            <textarea
                                name="reason"
                                required
                                minLength={5}
                                maxLength={2000}
                            />
                        </Field>
                        <p className="small">
                            Current timetables update after saving. Original COR
                            versions and the previous meeting times remain in
                            history.
                        </p>
                    </Panel>
                </SaveForm>
            ) : (
                <div className="form-stack">
                    {days.map((day, index) => {
                        const meetings = courses
                            .flatMap((c) =>
                                (c.meetings ?? [])
                                    .filter((m) => m.day === index + 1)
                                    .map((m) => ({ course: c, meeting: m })),
                            )
                            .sort((a, b) =>
                                a.meeting.start.localeCompare(b.meeting.start),
                            );
                        return meetings.length ? (
                            <Panel title={day} key={day}>
                                {meetings.map(
                                    ({ course: c, meeting: m }, i) => (
                                        <div
                                            className="record-item"
                                            key={`${c.id}-${i}`}
                                        >
                                            <div>
                                                <strong>
                                                    {m.start}–{m.end} ·{" "}
                                                    {c.subject.code}
                                                </strong>
                                                <p>
                                                    {c.subject.name} · Class{" "}
                                                    {c.section}
                                                </p>
                                                <small>
                                                    {c.teacher.name} ·{" "}
                                                    {c.branch.name} ·{" "}
                                                    {c.period.name}
                                                </small>
                                            </div>
                                            <a href={`/classes/${c.id}`}>
                                                View class
                                            </a>
                                        </div>
                                    ),
                                )}
                            </Panel>
                        ) : null;
                    })}
                    {courses.some((c) => !c.meetings?.length) && (
                        <Panel title="Timetables awaiting review">
                            {courses
                                .filter((c) => !c.meetings?.length)
                                .map((c) => (
                                    <p key={c.id}>
                                        {c.subject.code} · {c.section} ·{" "}
                                        {c.period.name}. Ask the School
                                        Administrator to confirm its weekly
                                        times.
                                    </p>
                                ))}
                        </Panel>
                    )}
                </div>
            )}
        </Shell>
    );
}
