import { ref, type Ref } from "vue";
import { router } from "@inertiajs/vue3";
import { useBuilderPrefix } from "./useBuilderPrefix";

export type TableState = {
  searchQuery: Ref<string>;
  sortColumn: Ref<string>;
  sortDirection: Ref<"asc" | "desc">;
  activeFilters: Ref<Record<string, string>>;
  perPage: Ref<number>;
  navigate: (overrides?: Record<string, string | undefined>) => void;
  toggleSort: (key: string) => void;
  setFilter: (key: string, value: string) => void;
  setPerPage: (n: number) => void;
};

export function useTableState(
  resourceSlug: string,
  filters: { key: string }[],
  currentLocale: string | null,
): TableState {
  const prefix = useBuilderPrefix();
  const urlParams = new URLSearchParams(window.location.search);

  const STORAGE_KEY = `builder.table.${resourceSlug}.per_page`;

  const searchQuery = ref(urlParams.get("search") ?? "");
  const sortColumn = ref(urlParams.get("column") ?? "");
  const sortDirection = ref<"asc" | "desc">(
    (urlParams.get("direction") as "asc" | "desc") ?? "asc",
  );
  const activeFilters = ref<Record<string, string>>({});
  const perPage = ref<number>(
    parseInt(urlParams.get("per_page") ?? "") ||
      parseInt(localStorage.getItem(STORAGE_KEY) ?? "") ||
      25,
  );

  // Init active filters from URL
  for (const f of filters) {
    const val = urlParams.get(f.key);
    if (val) {
      activeFilters.value[f.key] = val;
    }
  }

  function navigate(overrides: Record<string, string | undefined> = {}): void {
    const params: Record<string, string> = {};

    if (searchQuery.value) {
      params.search = searchQuery.value;
    }
    if (sortColumn.value) {
      params.column = sortColumn.value;
    }
    if (sortDirection.value !== "asc") {
      params.direction = sortDirection.value;
    }
    // Read locale from the live URL — stays correct after Inertia navigations
    const liveLocale = new URLSearchParams(window.location.search).get(
      "locale",
    );
    if (liveLocale) {
      params.locale = liveLocale;
    }
    if (perPage.value !== 25) {
      params.per_page = String(perPage.value);
    }

    for (const [k, v] of Object.entries(activeFilters.value)) {
      if (v) {
        params[k] = v;
      }
    }

    for (const [k, v] of Object.entries(overrides)) {
      if (v === undefined) {
        delete params[k];
      } else {
        params[k] = v;
      }
    }

    router.get(`/${prefix}/${resourceSlug}`, params, {
      preserveState: true,
      replace: true,
    });
  }

  function toggleSort(key: string): void {
    if (sortColumn.value === key) {
      sortDirection.value = sortDirection.value === "asc" ? "desc" : "asc";
    } else {
      sortColumn.value = key;
      sortDirection.value = "asc";
    }
    navigate({ column: sortColumn.value, direction: sortDirection.value });
  }

  function setFilter(key: string, value: string): void {
    if (value) {
      activeFilters.value[key] = value;
    } else {
      delete activeFilters.value[key];
    }
    navigate();
  }

  function setPerPage(n: number): void {
    perPage.value = n;
    localStorage.setItem(STORAGE_KEY, String(n));
    navigate({
      per_page: n !== 25 ? String(n) : undefined,
      page: undefined,
    });
  }

  return {
    searchQuery,
    sortColumn,
    sortDirection,
    activeFilters,
    perPage,
    navigate,
    toggleSort,
    setFilter,
    setPerPage,
  };
}
