import { Link } from "@inertiajs/react";
import { useEffect, useState } from "react";
import Shell from "../components/Shell";
import { periodName, yearOrGrade } from "../school-periods";
import {
    Alert,
    Badge,
    Button,
    ButtonLink,
    Confirm,
    Field,
    Heading,
    Panel,
    SaveForm,
} from "../components/ui";
import {
    person,
    type Course,
    type Enrollment as EnrollmentRecord,
    type Section,
} from "../types";

interface PlanRow {
    subject_id: number;
    code: string;
    name: string;
    units: string;
    classification: string | null;
    status: string;
    issues: string[];
    default_class_id: number | null;
}
interface Eligibility {
    academic_issues: string[];
    warnings: string[];
    financial_cleared: boolean;
    ready: boolean;
}
interface Props {
    application_id?: number | null;
    enrollment: EnrollmentRecord;
    eligibility: Eligibility | null;
    plan: PlanRow[];
    sections: Section[];
    offerings: Course[];
    locked_class_ids: number[];
    can_prepare: boolean;
    can_finalize: boolean;
    can_amend: boolean;
    can_capacity: boolean;
}
export default function Enrollment({
    application_id,
    enrollment: e,
    eligibility,
    plan,
    sections,
    offerings,
    locked_class_ids,
    can_prepare,
    can_finalize,
    can_amend,
    can_capacity,
}: Props) {
    const [confirm, setConfirm] = useState(false);
    const [amending, setAmending] = useState(false);
    const [selected, setSelected] = useState(e.courses.map((c) => c.id));
    const [section, setSection] = useState(String(e.section_id ?? ""));
    useEffect(() => {
        setSelected(e.courses.map((c) => c.id));
        setSection(String(e.section_id ?? ""));
        setAmending(false);
    }, [e.id, e.cor_version]);
    const classes = [
        ...new Map([...offerings, ...e.courses].map((c) => [c.id, c])).values(),
    ];
    const subjects = [
        ...new Map([
            ...classes.map(
                (c) =>
                    [
                        c.subject_id,
                        {
                            subject_id: c.subject_id,
                            code: c.subject.code,
                            name: c.subject.name,
                            units: c.subject.units,
                        },
                    ] as const,
            ),
            ...plan.map((p) => [p.subject_id, p] as const),
        ]).values(),
    ];
    const editor = can_prepare || (can_amend && amending);
    const choose = (subjectId: number, value: string) =>
        setSelected([
            ...selected.filter(
                (id) =>
                    classes.find((c) => c.id === id)?.subject_id !== subjectId,
            ),
            ...(value ? [Number(value)] : []),
        ]);
    const selectedSection = sections.find((s) => String(s.id) === section);
    const fullChoices = classes.filter(
        (c) => selected.includes(c.id) && (c.roster_count ?? 0) >= c.capacity,
    );
    return (
        <Shell title={"Enrollment · " + e.student.student_number}>
            <Heading
                title={person(e.student)}
                description={
                    e.student.student_number +
                    " · " +
                    e.period.name +
                    " · " +
                    e.branch.name
                }
                action={
                    e.status === "enrolled" ? (
                        <ButtonLink
                            href={"/enrollments/" + e.id + "/cor"}
                            icon="file"
                        >
                            View current COR
                        </ButtonLink>
                    ) : application_id ? (
                        <ButtonLink
                            href={`/enrollment-applications/${application_id}`}
                        >
                            Continue enrollment wizard
                        </ButtonLink>
                    ) : can_finalize ? (
                        <Button
                            disabled={!eligibility?.ready}
                            onClick={() => setConfirm(true)}
                        >
                            Finalize enrollment
                        </Button>
                    ) : undefined
                }
            />
            <Panel title="Enrollment details">
                <div className="form-grid">
                    <div>
                        <small>
                            {e.curriculum.program.level === "college"
                                ? "Course"
                                : "School level"}
                        </small>
                        <strong>{e.curriculum.program.name}</strong>
                    </div>
                    {e.curriculum.program.college && (
                        <div>
                            <small>College</small>
                            <strong>{e.curriculum.program.college.name}</strong>
                        </div>
                    )}
                    <div>
                        <small>School year</small>
                        <strong>{e.period.school_year}</strong>
                    </div>
                    <div>
                        <small>
                            {e.curriculum.program.level === "college"
                                ? "Year level"
                                : "Grade level"}
                        </small>
                        <strong>
                            {yearOrGrade(
                                e.curriculum.program.level,
                                e.year_level,
                            )}
                        </strong>
                    </div>
                    <div>
                        <small>
                            {e.period.kind === "semester"
                                ? "Semester"
                                : "Enrollment coverage"}
                        </small>
                        <strong>{periodName(e.period)}</strong>
                    </div>
                    <div>
                        <small>Curriculum</small>
                        <strong>{e.curriculum.version}</strong>
                    </div>
                    <div>
                        <small>Recorded Section</small>
                        <strong>
                            {e.section_snapshot?.name ??
                                e.section?.name ??
                                "Not assigned"}
                        </strong>
                    </div>
                    <div>
                        <small>Status</small>
                        <Badge
                            tone={
                                e.status === "enrolled" ? "success" : "warning"
                            }
                        >
                            {e.status === "enrolled"
                                ? "Enrolled · COR version " +
                                  (e.cor_version ?? 1)
                                : e.status === "cancelled"
                                  ? "Removed from batch"
                                  : "Draft · places not reserved"}
                        </Badge>
                    </div>
                </div>
            </Panel>
            <div className="two-columns">
                <div className="form-stack">
                    <Panel
                        title={
                            editor
                                ? amending
                                    ? "Amend enrolled subjects"
                                    : "Review subject load"
                                : "Enrolled subjects and current schedule"
                        }
                    >
                        {can_amend && !amending && (
                            <Button
                                type="button"
                                variant="secondary"
                                onClick={() => setAmending(true)}
                            >
                                Amend subjects or class selections
                            </Button>
                        )}
                        {editor ? (
                            <SaveForm
                                url={
                                    "/enrollments/" +
                                    e.id +
                                    (amending ? "/amend" : "/courses")
                                }
                                method={amending ? "post" : "put"}
                                label={
                                    amending
                                        ? "Apply amendment and issue new COR"
                                        : "Save reviewed subject load"
                                }
                                reset={false}
                                onSuccess={() => {
                                    if (amending) setAmending(false);
                                }}
                            >
                                <input
                                    type="hidden"
                                    name="course_ids"
                                    value={JSON.stringify(selected)}
                                />
                                {!amending && (
                                    <Field
                                        label="Section"
                                        hint="Existing current members retain their Section. This draft does not reserve a place."
                                    >
                                        <select
                                            name="section_id"
                                            value={section}
                                            onChange={(event) =>
                                                setSection(event.target.value)
                                            }
                                        >
                                            <option value="">
                                                No Section / individual class
                                                selections
                                            </option>
                                            {sections.map((s) => (
                                                <option key={s.id} value={s.id}>
                                                    {s.name} ·{" "}
                                                    {s.current_count ?? 0}/
                                                    {s.capacity} members
                                                </option>
                                            ))}
                                        </select>
                                    </Field>
                                )}
                                {subjects.map((subject) => {
                                    const row = plan.find(
                                        (p) =>
                                            p.subject_id === subject.subject_id,
                                    );
                                    const options = classes.filter(
                                        (c) =>
                                            c.subject_id === subject.subject_id,
                                    );
                                    const chosen = options.find((c) =>
                                        selected.includes(c.id),
                                    );
                                    const locked =
                                        !!chosen &&
                                        locked_class_ids.includes(chosen.id);
                                    const blocked =
                                        row?.status === "blocked" ||
                                        row?.status === "review";
                                    return (
                                        <fieldset
                                            className="subject-choice"
                                            key={subject.subject_id}
                                        >
                                            <legend>
                                                {subject.code} · {subject.name}
                                            </legend>
                                            <p className="small">
                                                {subject.units} units
                                                {row?.classification
                                                    ? " · " + row.classification
                                                    : ""}
                                                {row
                                                    ? " · " + row.status
                                                    : " · Additional curriculum subject"}
                                            </p>
                                            {row?.issues.map((issue) => (
                                                <p
                                                    className="field-error"
                                                    key={issue}
                                                >
                                                    {issue}
                                                </p>
                                            ))}
                                            {(row?.status === "passed" ||
                                                row?.status === "credited") && (
                                                <p className="small">
                                                    Already {row.status}. You
                                                    may still choose an
                                                    intentional retake.
                                                </p>
                                            )}
                                            {locked && (
                                                <Badge tone="success">
                                                    Final grade finalized ·
                                                    class selection locked
                                                </Badge>
                                            )}
                                            <Field
                                                label={
                                                    "Class for " + subject.code
                                                }
                                            >
                                                <select
                                                    value={chosen?.id ?? ""}
                                                    disabled={
                                                        locked ||
                                                        (blocked && !chosen)
                                                    }
                                                    onChange={(event) =>
                                                        choose(
                                                            subject.subject_id,
                                                            event.target.value,
                                                        )
                                                    }
                                                >
                                                    <option value="">
                                                        Not included in this
                                                        enrollment
                                                    </option>
                                                    {options.map((c) => (
                                                        <option
                                                            key={c.id}
                                                            value={c.id}
                                                            disabled={
                                                                !!c.finalized_at &&
                                                                !e.courses.some(
                                                                    (old) =>
                                                                        old.id ===
                                                                        c.id,
                                                                )
                                                            }
                                                        >
                                                            {c.section +
                                                                " · " +
                                                                c.teacher.name +
                                                                " · " +
                                                                (c.schedule ||
                                                                    "Times need review") +
                                                                ((c.roster_count ??
                                                                    0) >=
                                                                c.capacity
                                                                    ? " · Full"
                                                                    : "")}
                                                        </option>
                                                    ))}
                                                </select>
                                            </Field>
                                            {!options.length && (
                                                <p className="small">
                                                    No Subject Class is offered
                                                    for this subject in this
                                                    Branch and period. Ask the
                                                    School Administrator to
                                                    prepare it.
                                                </p>
                                            )}
                                        </fieldset>
                                    );
                                })}
                                {amending && (
                                    <>
                                        <Field label="Amendment reason">
                                            <textarea
                                                name="reason"
                                                required
                                                minLength={5}
                                                maxLength={2000}
                                            />
                                        </Field>
                                        <p className="small">
                                            All checks run again. A new COR
                                            version is issued and earlier
                                            versions are retained. Finalized
                                            grades lock their subjects against
                                            dropping or class switching.
                                        </p>
                                        <Button
                                            type="button"
                                            variant="ghost"
                                            onClick={() => {
                                                setSelected(
                                                    e.courses.map((c) => c.id),
                                                );
                                                setAmending(false);
                                            }}
                                        >
                                            Cancel amendment
                                        </Button>
                                    </>
                                )}
                                {!subjects.length && (
                                    <Alert
                                        title="No applicable subjects or classes are ready"
                                        tone="warning"
                                    >
                                        Review the curriculum’s Year/Grade and
                                        term mapping and the current-period
                                        Subject Classes.
                                    </Alert>
                                )}
                            </SaveForm>
                        ) : (
                            <div className="form-stack">
                                {e.courses.map((c) => (
                                    <article
                                        className="subject-choice"
                                        key={c.id}
                                    >
                                        <strong>
                                            {c.subject.code} · {c.subject.name}
                                        </strong>
                                        <p>
                                            Class {c.section} · {c.teacher.name}
                                        </p>
                                        <p>
                                            {c.schedule ||
                                                "Timetable awaiting review"}{" "}
                                            · {c.subject.units} units
                                        </p>
                                        {locked_class_ids.includes(c.id) && (
                                            <Badge tone="success">
                                                Final grade finalized
                                            </Badge>
                                        )}
                                    </article>
                                ))}
                            </div>
                        )}
                    </Panel>
                    {!!e.corVersions?.length && (
                        <Panel title="COR versions">
                            {e.corVersions.map((v) => (
                                <div className="record-item" key={v.id}>
                                    <div>
                                        <strong>
                                            Version {v.version}
                                            {v.version === 1
                                                ? " · Original"
                                                : ""}
                                            {v.version === e.cor_version
                                                ? " · Current"
                                                : ""}
                                        </strong>
                                        <small>
                                            {new Date(
                                                v.issued_at,
                                            ).toLocaleDateString("en-PH")}
                                        </small>
                                        {v.reason && <p>{v.reason}</p>}
                                    </div>
                                    <Link
                                        href={
                                            "/enrollments/" +
                                            e.id +
                                            "/cor?version=" +
                                            v.version
                                        }
                                    >
                                        View COR version {v.version}
                                    </Link>
                                </div>
                            ))}
                            <p className="small">
                                Current timetable views can reflect approved
                                rescheduling. Issued COR versions retain their
                                original details.
                            </p>
                        </Panel>
                    )}
                </div>
                <div className="form-stack">
                    {eligibility && (
                        <Panel title="Eligibility and clearance">
                            <Badge
                                tone={
                                    eligibility.academic_issues.length
                                        ? "warning"
                                        : "success"
                                }
                            >
                                {eligibility.academic_issues.length
                                    ? "Review required"
                                    : "Academic checks passed"}
                            </Badge>
                            {eligibility.academic_issues.map((issue) => (
                                <Alert
                                    title={issue}
                                    tone="warning"
                                    key={issue}
                                />
                            ))}
                            {eligibility.warnings?.map((issue) => (
                                <Alert
                                    title={issue}
                                    tone="warning"
                                    key={issue}
                                />
                            ))}
                            <div className="record-item">
                                <span>Financial clearance</span>
                                <Badge
                                    tone={
                                        eligibility.financial_cleared
                                            ? "success"
                                            : "warning"
                                    }
                                >
                                    {eligibility.financial_cleared
                                        ? "Cleared"
                                        : e.clearance?.status === "on_hold"
                                          ? "On Hold"
                                          : "Required / needs review"}
                                </Badge>
                            </div>
                            {e.clearance && (
                                <>
                                    <p>{e.clearance.reason}</p>
                                    {e.clearance.arrangement_terms && (
                                        <p>
                                            Approved payment terms:{" "}
                                            {e.clearance.arrangement_terms}
                                        </p>
                                    )}
                                </>
                            )}
                            <p className="small">
                                Finance Staff records clearance. Past-debt
                                payment arrangements require Finance Approver
                                approval. Prerequisites and timetable conflicts
                                cannot be overridden.
                            </p>
                        </Panel>
                    )}
                    {!!plan.length && (
                        <Panel title="Curriculum review">
                            {plan.map((row) => (
                                <div
                                    className="record-item"
                                    key={row.subject_id}
                                >
                                    <div>
                                        <strong>{row.code}</strong>
                                        <small>{row.name}</small>
                                    </div>
                                    <Badge
                                        tone={
                                            row.status === "blocked" ||
                                            row.status === "review"
                                                ? "warning"
                                                : row.status === "needed"
                                                  ? "info"
                                                  : "success"
                                        }
                                    >
                                        {row.status}
                                    </Badge>
                                </div>
                            ))}
                        </Panel>
                    )}
                    {can_capacity && (editor || e.status === "draft") && (
                        <Panel title="Capacity exceptions">
                            <p className="small">
                                Approval applies to one Student’s assignment and
                                leaves configured limits unchanged.
                            </p>
                            {selectedSection &&
                                (selectedSection.current_count ?? 0) >=
                                    selectedSection.capacity && (
                                    <details className="accordion">
                                        <summary>
                                            Review full Section:{" "}
                                            {selectedSection.name}
                                        </summary>
                                        <div>
                                            <SaveForm
                                                url={
                                                    "/enrollments/" +
                                                    e.id +
                                                    "/capacity"
                                                }
                                                label="Approve Section exception"
                                            >
                                                <input
                                                    type="hidden"
                                                    name="section_id"
                                                    value={selectedSection.id}
                                                />
                                                <Field label="Approval reason">
                                                    <textarea
                                                        name="reason"
                                                        required
                                                        minLength={5}
                                                        maxLength={2000}
                                                    />
                                                </Field>
                                            </SaveForm>
                                        </div>
                                    </details>
                                )}
                            {fullChoices.map((c) => (
                                <details key={c.id} className="accordion">
                                    <summary>
                                        Review full class: {c.subject.code} ·{" "}
                                        {c.section}
                                    </summary>
                                    <div>
                                        <SaveForm
                                            url={
                                                "/enrollments/" +
                                                e.id +
                                                "/capacity"
                                            }
                                            label="Approve class exception"
                                        >
                                            <input
                                                type="hidden"
                                                name="course_offering_id"
                                                value={c.id}
                                            />
                                            <Field label="Approval reason">
                                                <textarea
                                                    name="reason"
                                                    required
                                                    minLength={5}
                                                    maxLength={2000}
                                                />
                                            </Field>
                                        </SaveForm>
                                    </div>
                                </details>
                            ))}
                            <Link href="/capacity">
                                View capacity review list
                            </Link>
                        </Panel>
                    )}
                    <Panel>
                        <Link href="/enrollments">Back to enrollments</Link>
                    </Panel>
                </div>
            </div>
            {confirm && (
                <Confirm
                    title="Finalize this enrollment?"
                    url={"/enrollments/" + e.id + "/finalize"}
                    onClose={() => setConfirm(false)}
                >
                    Confirm the reviewed subjects, Section and schedule.
                    Academic, capacity, timetable and financial checks run again
                    before the COR is issued.
                </Confirm>
            )}
        </Shell>
    );
}
