import { useEffect, useId, useMemo, useState } from "react";
import {
  FormField,
  hasScope,
  type CalendarPickerProps
} from "@govoplan/core-webui";
import { listCalendars, type CalendarCollection } from "../../api/calendar";
import {
  CALENDAR_PICKER_READ_SCOPE,
  calendarPickerOptions,
  calendarPickerTenantId
} from "./calendarPickerLogic";

const LABEL = "i18n:govoplan-calendar.calendar.adab5090";
const SELECT_CALENDAR = "i18n:govoplan-calendar.select_calendar.f38b5ba2";
const LOADING_CALENDARS = "i18n:govoplan-calendar.loading_calendars.afbb957b";
const CALENDARS_UNAVAILABLE = "i18n:govoplan-calendar.calendars_are_unavailable.f074c862";
const NO_CALENDARS_AVAILABLE = "i18n:govoplan-calendar.no_calendars_are_available.711d2cf3";
const SELECTED_CALENDAR_UNAVAILABLE = "i18n:govoplan-calendar.the_selected_calendar_is_no_longer_available.39f0f1f5";

export default function CalendarPicker({
  settings,
  auth,
  value,
  onChange,
  id,
  name,
  label = LABEL,
  emptyLabel = SELECT_CALENDAR,
  disabled = false,
  required = false,
  className
}: CalendarPickerProps) {
  const generatedId = useId();
  const selectId = id ?? `calendar-picker-${generatedId.replace(/:/g, "")}`;
  const statusId = `${selectId}-status`;
  const [calendars, setCalendars] = useState<CalendarCollection[]>([]);
  const [loading, setLoading] = useState(false);
  const [failed, setFailed] = useState(false);
  const canRead = hasScope(auth, CALENDAR_PICKER_READ_SCOPE);
  const tenantId = calendarPickerTenantId(auth);

  useEffect(() => {
    let cancelled = false;
    if (!canRead) {
      setCalendars([]);
      setLoading(false);
      setFailed(true);
      return () => {
        cancelled = true;
      };
    }

    setLoading(true);
    setFailed(false);
    listCalendars(settings)
      .then((response) => {
        if (!cancelled) setCalendars(response.calendars);
      })
      .catch(() => {
        if (!cancelled) {
          setCalendars([]);
          setFailed(true);
        }
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [canRead, settings.accessToken, settings.apiBaseUrl, settings.apiKey, tenantId]);

  const options = useMemo(() => calendarPickerOptions(calendars), [calendars]);
  const selectedUnavailable = Boolean(value) && !loading && !options.some((calendar) => calendar.id === value);
  const status = failed
    ? CALENDARS_UNAVAILABLE
    : !loading && options.length === 0
      ? NO_CALENDARS_AVAILABLE
      : selectedUnavailable
        ? SELECTED_CALENDAR_UNAVAILABLE
        : "";
  const placeholder = loading
    ? LOADING_CALENDARS
    : failed
      ? CALENDARS_UNAVAILABLE
      : options.length === 0
        ? NO_CALENDARS_AVAILABLE
        : emptyLabel;

  return (
    <div className={["calendar-picker", className].filter(Boolean).join(" ")}>
      <FormField label={label}>
        <select
          id={selectId}
          name={name}
          value={value}
          required={required}
          disabled={disabled || loading || failed || options.length === 0}
          aria-busy={loading || undefined}
          aria-describedby={status ? statusId : undefined}
          onChange={(event) => onChange(event.target.value)}
        >
          <option value="">{placeholder}</option>
          {selectedUnavailable ? <option value={value} disabled>{SELECTED_CALENDAR_UNAVAILABLE}</option> : null}
          {options.map((calendar) => (
            <option key={calendar.id} value={calendar.id}>{calendar.name}</option>
          ))}
        </select>
      </FormField>
      {status ? <div id={statusId} className="muted small-note" role={failed ? "alert" : "status"}>{status}</div> : null}
    </div>
  );
}
