import { useState, useEffect, useCallback, useRef } from 'react';
import {
  UiUrlState,
  readUiUrlState,
  buildUiUrlStateSearch,
  paramsEqualExcept,
} from '../lib/urlState';

export function useUrlState() {
  const initialRef = useRef<UiUrlState | null>(null);
  if (!initialRef.current) {
    initialRef.current = readUiUrlState();
  }
  const initial = initialRef.current;

  const [urlState, setUrlState] = useState<UiUrlState>(initial);
  const urlSearchRef = useRef<string>(typeof window === 'undefined' ? '' : window.location.search);

  const applyUiUrlState = useCallback((nextStateOrFn: UiUrlState | ((prev: UiUrlState) => UiUrlState)) => {
    setUrlState(prev => {
      const nextState = typeof nextStateOrFn === 'function' ? nextStateOrFn(prev) : nextStateOrFn;
      return nextState;
    });
  }, []);

  useEffect(() => {
    if (typeof window === 'undefined') return;
    const onPopState = () => {
      urlSearchRef.current = window.location.search;
      applyUiUrlState(readUiUrlState());
    };
    window.addEventListener('popstate', onPopState);
    return () => window.removeEventListener('popstate', onPopState);
  }, [applyUiUrlState]);

  // Replace the current history entry with an explicit search string and sync
  // state from it. Used for one-shot URL normalization (e.g. rewriting a legacy
  // ?page=tasks deep link) where we must NOT add a history entry and must keep
  // urlSearchRef in sync so the regular pushUrlState effect then no-ops.
  const replaceUrlSearch = useCallback((nextSearch: string) => {
    if (typeof window === 'undefined') return;
    const normalized = nextSearch.startsWith('?') ? nextSearch.slice(1) : nextSearch;
    const nextUrl = `${window.location.pathname}${normalized ? `?${normalized}` : ''}${window.location.hash}`;
    window.history.replaceState(window.history.state, '', nextUrl);
    urlSearchRef.current = normalized ? `?${normalized}` : '';
    applyUiUrlState(readUiUrlState());
  }, [applyUiUrlState]);

  const pushUrlState = useCallback((nextState: UiUrlState) => {
    if (typeof window === 'undefined') return;
    const nextSearch = buildUiUrlStateSearch(nextState);
    const previousSearch = urlSearchRef.current.startsWith('?')
      ? urlSearchRef.current.slice(1)
      : urlSearchRef.current;
    if (nextSearch === previousSearch) return;

    const nextParams = new URLSearchParams(nextSearch);
    const previousParams = new URLSearchParams(previousSearch);
    const nextUrl = `${window.location.pathname}${nextSearch ? `?${nextSearch}` : ''}${window.location.hash}`;
    // 検索欄はキー入力ごとに値が変わるため history を汚さないよう replace 扱いにする。
    // q=タスクページ検索 / sq=ワークスペース・チャット検索。
    const shouldReplace = paramsEqualExcept(previousParams, nextParams, ['q', 'sq']);
    window.history[shouldReplace ? 'replaceState' : 'pushState'](window.history.state, '', nextUrl);
    urlSearchRef.current = nextSearch ? `?${nextSearch}` : '';
  }, []);

  return { urlState, setUrlState: applyUiUrlState as (nextStateOrFn: UiUrlState | ((prev: UiUrlState) => UiUrlState)) => void, pushUrlState, replaceUrlSearch };
}
