'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react';
import { usePathname, useRouter } from 'next/navigation';
import {
  DEFAULT_REGION_SLUG,
  homePath,
  markGeolocAttempted,
  parseRegionFromPath,
  parseServiceArea,
  readGeolocAttempted,
  regionLabel,
  regionPath,
  readStoredRegionSlug,
  SERVICE_AREA_LABELS,
  storeRegionSlug,
  type ServiceArea,
} from '@/lib/region';
import { detectRegionSlugFromBrowser } from '@/lib/regionGeolocation';

interface RegionContextValue {
  slug: string;
  area: ServiceArea;
  label: string;
  isRegionalRoute: boolean;
  /** False until client has read persisted region (avoids unfiltered home fetches). */
  regionReady: boolean;
  setRegion: (slug: string, options?: { subpath?: string }) => void;
  regionPath: (subpath?: string) => string;
  homePath: () => string;
}

const RegionContext = createContext<RegionContextValue | null>(null);

function subpathFromRegionalRoute(pathname: string, slug: string): string {
  const prefix = `/region/${slug}`;
  if (pathname === prefix) return '';
  if (pathname.startsWith(`${prefix}/`)) {
    return pathname.slice(prefix.length);
  }
  return '';
}

export function RegionProvider({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  const router = useRouter();
  const [storedSlug, setStoredSlug] = useState<string | null>(() =>
    typeof window === 'undefined' ? null : readStoredRegionSlug(),
  );
  const [hasHydrated, setHasHydrated] = useState(false);
  const [geolocResolved, setGeolocResolved] = useState(() => {
    if (typeof window === 'undefined') return false;
    return Boolean(readStoredRegionSlug() || readGeolocAttempted());
  });

  useEffect(() => {
    setStoredSlug(readStoredRegionSlug());
    setHasHydrated(true);
  }, []);

  useEffect(() => {
    if (parseRegionFromPath(pathname)) {
      setGeolocResolved(true);
      return;
    }

    if (readStoredRegionSlug() || readGeolocAttempted()) {
      setGeolocResolved(true);
      return;
    }

    markGeolocAttempted();
    let cancelled = false;

    void (async () => {
      const detectedSlug = await detectRegionSlugFromBrowser();
      if (cancelled) return;

      if (detectedSlug) {
        storeRegionSlug(detectedSlug);
        setStoredSlug(detectedSlug);
      }
      setGeolocResolved(true);
    })();

    return () => {
      cancelled = true;
    };
  }, [pathname]);

  const slugFromPath = parseRegionFromPath(pathname);
  const slug = slugFromPath ?? storedSlug ?? DEFAULT_REGION_SLUG;
  const area = parseServiceArea(slug) ?? 'ENTIRE_PHILIPPINES';
  const isRegionalRoute = slugFromPath != null;

  useEffect(() => {
    if (slugFromPath) storeRegionSlug(slugFromPath);
  }, [slugFromPath]);

  const setRegion = useCallback(
    (newSlug: string, options?: { subpath?: string }) => {
      if (!parseServiceArea(newSlug)) return;
      storeRegionSlug(newSlug);
      setStoredSlug(newSlug);

      const subpath =
        options?.subpath ??
        (isRegionalRoute ? subpathFromRegionalRoute(pathname, slugFromPath ?? slug) : '');

      if (newSlug === DEFAULT_REGION_SLUG && !subpath) {
        router.push('/');
        return;
      }

      router.push(regionPath(newSlug, subpath));
    },
    [isRegionalRoute, pathname, router, slug, slugFromPath]
  );

  const value = useMemo<RegionContextValue>(
    () => ({
      slug,
      area,
      label: regionLabel(slug),
      isRegionalRoute,
      regionReady: slugFromPath != null || (hasHydrated && geolocResolved),
      setRegion,
      regionPath: (subpath = '') => regionPath(slug, subpath),
      homePath: () => homePath(slug),
    }),
    [area, geolocResolved, hasHydrated, isRegionalRoute, setRegion, slug, slugFromPath]
  );

  return <RegionContext.Provider value={value}>{children}</RegionContext.Provider>;
}

export function useRegion() {
  const ctx = useContext(RegionContext);
  if (!ctx) {
    throw new Error('useRegion must be used within RegionProvider');
  }
  return ctx;
}

export function useRegionLabel(slug?: string) {
  return slug ? regionLabel(slug) : SERVICE_AREA_LABELS.ENTIRE_PHILIPPINES;
}
