"use client";

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

import {
  createTranslation,
  deleteTranslation,
  enableTranslation,
  getTranslationPages,
  getTranslations,
  updateTranslation,
} from "../service/translation-service";

import type {
  Translation,
  TranslationFormData,
  TranslationMeta,
  TranslationModule,
  TranslationPageOption,
} from "../types/translation-types";

export type TranslationStatusFilter =
  | "all"
  | "active"
  | "inactive";

export type TranslationModuleFilter =
  | "all"
  | TranslationModule;

export type TranslationPageFilter =
  | "all"
  | string;

const EMPTY_META:
  TranslationMeta = {
  page: 1,
  limit: 10,
  total: 0,
  totalPages: 0,
  hasNextPage: false,
  hasPreviousPage: false,
};

export function useTranslations() {
  const [
    items,
    setItems,
  ] =
    useState<
      Translation[]
    >([]);

  const [
    meta,
    setMeta,
  ] =
    useState<
      TranslationMeta
    >(EMPTY_META);

  const [
    page,
    setPage,
  ] =
    useState(1);

  const [
    search,
    setSearch,
  ] =
    useState("");

  const [
    moduleFilter,
    setModuleFilter,
  ] =
    useState<
      TranslationModuleFilter
    >("all");

  const [
    pageFilter,
    setPageFilter,
  ] =
    useState<
      TranslationPageFilter
    >("all");

  const [
    pageOptions,
    setPageOptions,
  ] =
    useState<
      TranslationPageOption[]
    >([]);

  const [
    loadingPageOptions,
    setLoadingPageOptions,
  ] =
    useState(false);

  const [
    pageOptionsError,
    setPageOptionsError,
  ] =
    useState("");

  const [
    statusFilter,
    setStatusFilter,
  ] =
    useState<
      TranslationStatusFilter
    >("all");

  const [
    loading,
    setLoading,
  ] =
    useState(true);

  const [
    saving,
    setSaving,
  ] =
    useState(false);

  const [
    error,
    setError,
  ] =
    useState("");

  const loadTranslations =
    useCallback(
      async () => {
        setLoading(true);
        setError("");

        try {
          const data =
            await getTranslations({
              page,
              limit: 10,
              search:
                search.trim() ||
                undefined,
              module:
                moduleFilter ===
                "all"
                  ? undefined
                  : moduleFilter,
              pageKey:
                pageFilter ===
                "all"
                  ? undefined
                  : pageFilter,
              isActive:
                statusFilter ===
                "active"
                  ? true
                  : statusFilter ===
                      "inactive"
                    ? false
                    : undefined,
            });

          setItems(
            data.items,
          );

          setMeta(
            data.meta,
          );
        } catch (err) {
          setError(
            err instanceof Error
              ? err.message
              : "Unable to load translations.",
          );
        } finally {
          setLoading(false);
        }
      },
      [
        moduleFilter,
        page,
        pageFilter,
        search,
        statusFilter,
      ],
    );

  useEffect(() => {
    const timer =
      window.setTimeout(
        () => {
          void loadTranslations();
        },
        250,
      );

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

  // ============================================================
  // PAGE OPTIONS FOR FILTER
  // Load pages only after a specific module is selected.
  // Uses a timeout so there is no synchronous setState inside effect.
  // ============================================================

  useEffect(() => {
    if (
      moduleFilter ===
      "all"
    ) {
      return;
    }

    let cancelled =
      false;

    const timer =
      window.setTimeout(
        () => {
          void (async () => {
            if (cancelled) {
              return;
            }

            setLoadingPageOptions(
              true,
            );
            setPageOptionsError(
              "",
            );

            try {
              const result =
                await getTranslationPages(
                  moduleFilter,
                );

              if (cancelled) {
                return;
              }

              setPageOptions(
                result,
              );
            } catch (err) {
              if (cancelled) {
                return;
              }

              setPageOptions(
                [],
              );

              setPageOptionsError(
                err instanceof Error
                  ? err.message
                  : "Unable to load pages.",
              );
            } finally {
              if (!cancelled) {
                setLoadingPageOptions(
                  false,
                );
              }
            }
          })();
        },
        0,
      );

    return () => {
      cancelled = true;
      window.clearTimeout(
        timer,
      );
    };
  }, [
    moduleFilter,
  ]);

  const createItem =
    async (
      data:
        TranslationFormData,
    ) => {
      setSaving(true);
      setError("");

      try {
        const result =
          await createTranslation(
            data,
          );

        await loadTranslations();

        return result;
      } finally {
        setSaving(false);
      }
    };

  const updateItem =
    async (
      id: number,
      data:
        Partial<TranslationFormData>,
    ) => {
      setSaving(true);
      setError("");

      try {
        const result =
          await updateTranslation(
            id,
            data,
          );

        await loadTranslations();

        return result;
      } finally {
        setSaving(false);
      }
    };

  const deleteItem =
    async (
      id: number,
    ) => {
      setError("");

      const result =
        await deleteTranslation(
          id,
        );

      await loadTranslations();

      return result;
    };

  const enableItem =
    async (
      id: number,
    ) => {
      setError("");

      const result =
        await enableTranslation(
          id,
        );

      await loadTranslations();

      return result;
    };

  const resetFilters = () => {
    setSearch("");
    setModuleFilter(
      "all",
    );
    setPageFilter(
      "all",
    );
    setPageOptions(
      [],
    );
    setPageOptionsError(
      "",
    );
    setStatusFilter(
      "all",
    );
    setPage(1);
  };

  return {
    items,
    meta,
    page,
    search,
    moduleFilter,
    pageFilter,
    pageOptions,
    loadingPageOptions,
    pageOptionsError,
    statusFilter,
    loading,
    saving,
    error,

    setPage,
    setSearch,
    setModuleFilter,
    setPageFilter,
    setPageOptions,
    setPageOptionsError,
    setStatusFilter,
    setError,

    createItem,
    updateItem,
    deleteItem,
    enableItem,
    resetFilters,

    reload:
      loadTranslations,
  };
}