'use client';

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

import { useLocalStorage, useMediaQuery } from '@djangocfg/ui-core/hooks';

import { CSS_VARS, DEFAULT_SIDEBAR, STORAGE_KEYS } from '../config';
import type { ChatDisplayMode } from '../types';

export interface UseChatLayoutConfig {
  defaultMode?: ChatDisplayMode;
  storageKey?: string;
  sidebarStorageKey?: string;
  reserveCssVar?: string;
  defaultSidebarWidth?: number;
  minSidebarWidth?: number;
  maxSidebarWidth?: number;
  /** Mobile breakpoint, e.g. '(max-width: 640px)'. */
  mobileQuery?: string;
}

export interface UseChatLayoutReturn {
  mode: ChatDisplayMode;
  setMode: (m: ChatDisplayMode) => void;
  open: () => void;
  close: () => void;
  toggle: () => void;
  sidebarWidth: number;
  setSidebarWidth: (w: number) => void;
  isMobile: boolean;
  /** Mode after mobile collapse rules — sidebar/floating become fullscreen on mobile. */
  effectiveMode: ChatDisplayMode;
}

const DEFAULT_MOBILE_QUERY = '(max-width: 640px)';

export function useChatLayout(config: UseChatLayoutConfig = {}): UseChatLayoutReturn {
  const {
    defaultMode = 'closed',
    storageKey = STORAGE_KEYS.mode,
    sidebarStorageKey = STORAGE_KEYS.sidebarWidth,
    reserveCssVar = CSS_VARS.reserve,
    defaultSidebarWidth = DEFAULT_SIDEBAR.width,
    minSidebarWidth = DEFAULT_SIDEBAR.min,
    maxSidebarWidth = DEFAULT_SIDEBAR.max,
    mobileQuery = DEFAULT_MOBILE_QUERY,
  } = config;

  const [mode, setMode] = useLocalStorage<ChatDisplayMode>(storageKey, defaultMode);
  const [sidebarWidthRaw, setSidebarWidthRaw] = useLocalStorage<number>(
    sidebarStorageKey,
    defaultSidebarWidth,
  );
  const isMobile = useMediaQuery(mobileQuery);

  const setSidebarWidth = useCallback(
    (w: number) => {
      const clamped = Math.max(minSidebarWidth, Math.min(maxSidebarWidth, w));
      setSidebarWidthRaw(clamped);
    },
    [setSidebarWidthRaw, minSidebarWidth, maxSidebarWidth],
  );

  const [previousOpenMode, setPreviousOpenMode] = useState<ChatDisplayMode>(
    mode === 'closed' ? 'embedded' : mode,
  );
  useEffect(() => {
    if (mode !== 'closed') setPreviousOpenMode(mode);
  }, [mode]);

  const open = useCallback(() => {
    setMode(previousOpenMode === 'closed' ? 'embedded' : previousOpenMode);
  }, [setMode, previousOpenMode]);

  const close = useCallback(() => setMode('closed'), [setMode]);
  const toggle = useCallback(() => {
    setMode((mode === 'closed' ? previousOpenMode : 'closed') as ChatDisplayMode);
  }, [setMode, mode, previousOpenMode]);

  const effectiveMode = useMemo<ChatDisplayMode>(() => {
    if (mode === 'closed') return 'closed';
    if (isMobile && (mode === 'sidebar' || mode === 'floating')) return 'fullscreen';
    return mode;
  }, [mode, isMobile]);

  // Reserve right padding when in sidebar mode.
  useEffect(() => {
    if (typeof document === 'undefined') return;
    const root = document.documentElement;
    if (effectiveMode === 'sidebar') {
      root.style.setProperty(reserveCssVar, `${sidebarWidthRaw}px`);
    } else {
      root.style.removeProperty(reserveCssVar);
    }
    return () => {
      root.style.removeProperty(reserveCssVar);
    };
  }, [effectiveMode, sidebarWidthRaw, reserveCssVar]);

  return {
    mode,
    setMode,
    open,
    close,
    toggle,
    sidebarWidth: sidebarWidthRaw,
    setSidebarWidth,
    isMobile,
    effectiveMode,
  };
}
