import { useEffect, useRef, useState } from "react";

import PageHeader from "@/components/PageHeader";
import { useEventsActions } from "@/hooks/useEventsActions";
import { useEventsStore } from "@/stores/useEventsStore";
import type { ApiEvent, ApiEventAsset } from "@/types";
import { formatEventDate } from "@/utils/eventDate";
import calendarIcon from "../../images/icons/calender-icon.svg";
import downArrowIcon from "../../images/icons/down-arrow.svg";
import guideIcon from "../../images/icons/guid-icon.svg";
import mapIcon from "../../images/icons/map-icon.svg";
import rightArrowIcon from "../../images/icons/right-arrow.svg";
import tvIcon from "../../images/icons/tv-icon.svg";

type ResourceType = "agenda" | "document" | "map" | "slides";

const resourceIcons: Record<ResourceType, string> = {
    agenda: calendarIcon,
    document: guideIcon,
    map: mapIcon,
    slides: tvIcon,
};

const formatFileSize = (size: number | null) => {
    if (!size) {
        return "";
    }

    const kb = size / 1024;

    if (kb < 1024) {
        return `${Math.max(1, Math.round(kb))} KB`;
    }

    return `${(kb / 1024).toFixed(1)} MB`;
};

const getResourceType = (asset: ApiEventAsset): ResourceType => {
    const title = (asset.title ?? asset.file_name ?? "").toLowerCase();
    const format = asset.format.toLowerCase();

    if (format.includes("ppt")) {
        return "slides";
    }

    if (title.includes("map")) {
        return "map";
    }

    if (title.includes("agenda") || title.includes("schedule")) {
        return "agenda";
    }

    return "document";
};

const groupAssets = (assets: ApiEventAsset[] = []) => {
    return assets.reduce<Record<string, ApiEventAsset[]>>((groups, asset) => {
        const label = asset.category.label;

        return {
            ...groups,
            [label]: [...(groups[label] ?? []), asset],
        };
    }, {});
};

const EventThumb = ({ event }: { event: ApiEvent }) => (
    <img
        className="lsi-event-thumb flex-shrink-0"
        src={event.image ?? undefined}
        alt=""
        aria-hidden="true"
    />
);

const ResourceIcon = ({ type }: { type: ResourceType }) => (
    <span
        className="lsi-resource-icon d-inline-flex align-items-center justify-content-center flex-shrink-0"
        aria-hidden="true"
    >
        <img src={resourceIcons[type]} alt="" />
    </span>
);

const EventAssetsPage = () => {
    const { error, events, isLoading } = useEventsStore();
    const { fetchEvents } = useEventsActions();
    const [openEventIds, setOpenEventIds] = useState<number[]>([]);
    const firstEventId = events[0]?.id;
    const seededFor = useRef<number | undefined>(undefined);

    useEffect(() => {
        void fetchEvents();
    }, []);

    // Open the first event once, when a list arrives. Keying this on
    // openEventIds.length instead (as it used to) meant collapsing the last
    // open panel re-fired the effect and immediately re-opened this one — the
    // first event could never be closed.
    useEffect(() => {
        if (firstEventId !== undefined && seededFor.current !== firstEventId) {
            seededFor.current = firstEventId;
            setOpenEventIds([firstEventId]);
        }
    }, [firstEventId]);

    const toggleEvent = (eventId: number) => {
        setOpenEventIds((current) =>
            current.includes(eventId)
                ? current.filter((id) => id !== eventId)
                : [...current, eventId],
        );
    };

    return (
        <article className="portal-card from-lsi-page event-assets-page">
            <PageHeader
                eyebrowParent="From LSI"
                eyebrowCurrent="Event Assets"
                title="LSI event assets"
                description="Attendee guides, presenter resources, and everything else you need to show up prepared - grouped by event."
            />

            <section className="from-lsi-panel">
                <p className="from-lsi-panel__intro mb-0">
                    Resources organized by event - expand to see what's
                    available
                </p>

                <div className="from-lsi-divider" />

                {error ? (
                    <p className="alert alert-danger mb-4" role="alert">
                        {error}
                    </p>
                ) : null}

                {isLoading ? (
                    <p className="text-muted">Loading event assets…</p>
                ) : events.length === 0 ? (
                    <p className="text-muted mb-0">
                        No event assets available.
                    </p>
                ) : (
                    <div className="d-flex flex-column gap-4">
                        {events.map((event) => {
                            const isOpen = openEventIds.includes(event.id);
                            const panelId = `event-assets-panel-${event.id}`;
                            const assetGroups = groupAssets(event.assets);
                            const assetGroupEntries =
                                Object.entries(assetGroups);

                            return (
                                <section
                                    className="lsi-event-card bg-white"
                                    key={event.id}
                                >
                                    <button
                                        className="lsi-event-toggle d-flex align-items-center gap-3 gap-md-4 w-100 border-0 bg-transparent text-start"
                                        type="button"
                                        aria-controls={panelId}
                                        aria-expanded={isOpen}
                                        onClick={() => toggleEvent(event.id)}
                                    >
                                        <EventThumb event={event} />

                                        <span className="min-w-0 flex-grow-1">
                                            <span className="lsi-event-title d-block mb-2">
                                                {event.name}
                                            </span>
                                            <span className="lsi-event-meta d-block mb-0">
                                                {formatEventDate(event)}{" "}
                                                &middot; {event.location}
                                            </span>
                                        </span>

                                        <img
                                            className="lsi-row-arrow flex-shrink-0"
                                            src={
                                                isOpen
                                                    ? downArrowIcon
                                                    : rightArrowIcon
                                            }
                                            alt=""
                                            aria-hidden="true"
                                        />
                                    </button>

                                    {isOpen ? (
                                        <div
                                            className="lsi-resource-groups"
                                            id={panelId}
                                        >
                                            {assetGroupEntries.length ? (
                                                assetGroupEntries.map(
                                                    ([
                                                        groupTitle,
                                                        resources,
                                                    ]) => (
                                                        <div
                                                            className="lsi-resource-group"
                                                            key={groupTitle}
                                                        >
                                                            <h3>
                                                                {groupTitle}
                                                            </h3>

                                                            <div className="d-flex flex-column gap-3">
                                                                {resources.map(
                                                                    (
                                                                        resource,
                                                                    ) => (
                                                                        <a
                                                                            className="lsi-resource-row d-flex align-items-center gap-3 text-decoration-none"
                                                                            href={
                                                                                resource.file ??
                                                                                "#event-resource"
                                                                            }
                                                                            key={
                                                                                resource.id
                                                                            }
                                                                            rel="noreferrer"
                                                                            target={
                                                                                resource.file
                                                                                    ? "_blank"
                                                                                    : undefined
                                                                            }
                                                                        >
                                                                            <ResourceIcon
                                                                                type={getResourceType(
                                                                                    resource,
                                                                                )}
                                                                            />
                                                                            <span className="min-w-0 flex-grow-1">
                                                                                <span className="lsi-resource-title d-block">
                                                                                    {resource.title ??
                                                                                        resource.file_name ??
                                                                                        "Event asset"}
                                                                                </span>
                                                                                <span className="lsi-resource-meta d-block">
                                                                                    {
                                                                                        resource.format
                                                                                    }
                                                                                    {formatFileSize(
                                                                                        resource.size,
                                                                                    )
                                                                                        ? ` - ${formatFileSize(resource.size)}`
                                                                                        : ""}
                                                                                </span>
                                                                            </span>
                                                                            <img
                                                                                className="lsi-row-arrow"
                                                                                src={
                                                                                    rightArrowIcon
                                                                                }
                                                                                alt=""
                                                                                aria-hidden="true"
                                                                            />
                                                                        </a>
                                                                    ),
                                                                )}
                                                            </div>
                                                        </div>
                                                    ),
                                                )
                                            ) : (
                                                <p className="text-muted mb-0">
                                                    No assets available for this
                                                    event.
                                                </p>
                                            )}
                                        </div>
                                    ) : null}
                                </section>
                            );
                        })}
                    </div>
                )}
            </section>
        </article>
    );
};

export default EventAssetsPage;
