"use client";

import {
  useCallback,
  useEffect,
  useMemo,
  useState,
} from "react";

import type {
  MinistryRgcDecisionRow,
  MinistryRgcDecisionStatus,
} from "../data/ministry-rgc-decision-data";
import { getMinistryRgcDecisions } from "../service/ministry-rgc-decision-service";

export function useMinistryRgcDecisions() {
  const [rows, setRows] = useState<MinistryRgcDecisionRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [selectedStatuses, setSelectedStatuses] =
    useState<MinistryRgcDecisionStatus[]>([]);

  const [
    selectedPrimaryAgencyIds,
    setSelectedPrimaryAgencyIds,
  ] = useState<number[]>([]);

  const [selectedCategoryIds, setSelectedCategoryIds] =
    useState<number[]>([]);

  // Format: YYYY-MM
  const [meetingDate, setMeetingDate] = useState("");

  const reload = useCallback(async () => {
    setLoading(true);
    setError(null);

    try {
      const decisions = await getMinistryRgcDecisions();
      setRows(decisions);
    } catch (requestError) {
      setRows([]);

      setError(
        requestError instanceof Error
          ? requestError.message
          : "Unable to load RGC Decisions.",
      );
    } finally {
      setLoading(false);
    }
  }, []);

  /*
   * Use a scheduled callback instead of calling reload directly
   * inside the effect. This avoids React's set-state-in-effect warning.
   */
  useEffect(() => {
    const timeoutId = window.setTimeout(() => {
      void reload();
    }, 0);

    return () => {
      window.clearTimeout(timeoutId);
    };
  }, [reload]);

  const filteredRows = useMemo(() => {
    return rows.filter((row) => {
      const matchStatus =
        selectedStatuses.length === 0 ||
        selectedStatuses.includes(row.status);

      const matchAgency =
        selectedPrimaryAgencyIds.length === 0 ||
        (row.ministryId !== null &&
          selectedPrimaryAgencyIds.includes(row.ministryId));

      const matchCategory =
        selectedCategoryIds.length === 0 ||
        (row.categoryId !== null &&
          selectedCategoryIds.includes(row.categoryId));

      const rowMonth = row.meetingDate
        ? row.meetingDate.slice(0, 7)
        : "";

      const matchMeetingDate =
        meetingDate === "" || rowMonth === meetingDate;

      return (
        matchStatus &&
        matchAgency &&
        matchCategory &&
        matchMeetingDate
      );
    });
  }, [
    rows,
    selectedStatuses,
    selectedPrimaryAgencyIds,
    selectedCategoryIds,
    meetingDate,
  ]);

  const toggleStatus = useCallback(
    (status: MinistryRgcDecisionStatus) => {
      setSelectedStatuses((current) =>
        current.includes(status)
          ? current.filter((item) => item !== status)
          : [...current, status],
      );
    },
    [],
  );

  const togglePrimaryAgency = useCallback((id: number) => {
    setSelectedPrimaryAgencyIds((current) =>
      current.includes(id)
        ? current.filter((item) => item !== id)
        : [...current, id],
    );
  }, []);

  const toggleCategory = useCallback((id: number) => {
    setSelectedCategoryIds((current) =>
      current.includes(id)
        ? current.filter((item) => item !== id)
        : [...current, id],
    );
  }, []);

  const selectAllStatuses = useCallback(
    (allStatuses: MinistryRgcDecisionStatus[]) => {
      setSelectedStatuses((current) =>
        current.length === allStatuses.length
          ? []
          : [...allStatuses],
      );
    },
    [],
  );

  const selectAllPrimaryAgencies = useCallback(
    (allIds: number[]) => {
      setSelectedPrimaryAgencyIds((current) =>
        current.length === allIds.length
          ? []
          : [...allIds],
      );
    },
    [],
  );

  const selectAllCategories = useCallback(
    (allIds: number[]) => {
      setSelectedCategoryIds((current) =>
        current.length === allIds.length
          ? []
          : [...allIds],
      );
    },
    [],
  );

  const resetFilters = useCallback(() => {
    setSelectedStatuses([]);
    setSelectedPrimaryAgencyIds([]);
    setSelectedCategoryIds([]);
    setMeetingDate("");
  }, []);

  return {
    rows,
    filteredRows,
    loading,
    error,

    selectedStatuses,
    selectedPrimaryAgencyIds,
    selectedCategoryIds,
    meetingDate,

    toggleStatus,
    togglePrimaryAgency,
    toggleCategory,

    selectAllStatuses,
    selectAllPrimaryAgencies,
    selectAllCategories,

    setMeetingDate,
    resetFilters,
    reload,
  };
}

export default useMinistryRgcDecisions;