'use client';

import {
  useCallback,
  useEffect,
  useState,
} from 'react';

import type {
  PlenaryApiItem,
  PlenaryListFilters,
  PlenaryMeta,
} from '../plenary-data';
import { getPlenaries } from '../service/plenary-service';

const DEFAULT_META: PlenaryMeta = {
  total: 0,
  page: 1,
  limit: 10,
  totalPages: 1,
};

const EMPTY_FILTERS: PlenaryListFilters = {
  ministryIds: [],
  statuses: [],
};

function getErrorMessage(error: unknown): string {
  if (error instanceof Error && error.message.trim()) {
    return error.message;
  }

  return 'Unable to load plenaries.';
}

export function usePlenaries() {
  const [items, setItems] = useState<PlenaryApiItem[]>([]);
  const [meta, setMeta] =
    useState<PlenaryMeta>(DEFAULT_META);

  const [filters, setFilters] =
    useState<PlenaryListFilters>(EMPTY_FILTERS);

  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const requestPlenaries = useCallback(
    async (
      page: number,
      limit: number,
      currentFilters: PlenaryListFilters,
    ) => {
      setLoading(true);
      setError(null);

      try {
        const data = await getPlenaries(
          page,
          limit,
          currentFilters,
        );

        setItems(data.items ?? []);
        setMeta(data.meta ?? DEFAULT_META);
      } catch (loadError: unknown) {
        setItems([]);
        setMeta(DEFAULT_META);
        setError(getErrorMessage(loadError));
      } finally {
        setLoading(false);
      }
    },
    [],
  );

  const loadPlenaries = useCallback(
    async (page = 1, limit = 10) => {
      await requestPlenaries(page, limit, filters);
    },
    [filters, requestPlenaries],
  );

  const applyFilters = useCallback(
    async (nextFilters: PlenaryListFilters) => {
      const normalizedFilters: PlenaryListFilters = {
        ministryIds: [
          ...new Set(nextFilters.ministryIds ?? []),
        ],
        statuses: [
          ...new Set(nextFilters.statuses ?? []),
        ],
        search: nextFilters.search?.trim() || undefined,
      };

      setFilters(normalizedFilters);

      await requestPlenaries(
        1,
        DEFAULT_META.limit,
        normalizedFilters,
      );
    },
    [requestPlenaries],
  );

  const clearFilters = useCallback(async () => {
    setFilters(EMPTY_FILTERS);

    await requestPlenaries(
      1,
      DEFAULT_META.limit,
      EMPTY_FILTERS,
    );
  }, [requestPlenaries]);

  useEffect(() => {
    /*
     * Timer avoids React warning about synchronous setState
     * directly inside useEffect.
     */
    const timer = window.setTimeout(() => {
      void requestPlenaries(
        1,
        DEFAULT_META.limit,
        EMPTY_FILTERS,
      );
    }, 0);

    return () => {
      window.clearTimeout(timer);
    };
  }, [requestPlenaries]);

  return {
    items,
    meta,
    loading,
    error,
    filters,
    loadPlenaries,
    applyFilters,
    clearFilters,
  };
}