'use client';

import { useEffect, useId, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import {
  Check,
  ChevronDown,
  ChevronRight,
  Globe2,
  MapPin,
  Search,
  X,
} from 'lucide-react';
import {
  CITY_DEFINITIONS,
  ISLAND_GROUP_IDS,
  ISLAND_GROUP_LABELS,
  isEntireRegion,
  type IslandGroupId,
  type ServiceArea,
} from '@ehandyhire/shared';
import { REGION_OPTION_GROUPS, regionLabel } from '@/lib/region';
import { cn } from '@/lib/utils';

export interface RegionPickerOption {
  area: string;
  slug: string;
  label: string;
  groupId: string;
  groupLabel: string;
}

const QUICK_PICK_GROUP_IDS = new Set(['country', 'islands']);

const ALL_OPTIONS: RegionPickerOption[] = REGION_OPTION_GROUPS.flatMap((group) =>
  group.options.map((option) => ({
    ...option,
    groupId: group.id,
    groupLabel: group.label,
  }))
);

const QUICK_PICKS = ALL_OPTIONS.filter((o) => QUICK_PICK_GROUP_IDS.has(o.groupId));

const ADMIN_GROUPS = REGION_OPTION_GROUPS.filter(
  (g) => !QUICK_PICK_GROUP_IDS.has(g.id)
);

const ADMIN_REGION_ISLAND = new Map<string, IslandGroupId>();
for (const city of CITY_DEFINITIONS) {
  if (!ADMIN_REGION_ISLAND.has(city.adminRegion)) {
    ADMIN_REGION_ISLAND.set(city.adminRegion, city.islandGroup);
  }
}

type IslandFilter = 'ALL' | IslandGroupId;

const ISLAND_FILTERS: { id: IslandFilter; label: string }[] = [
  { id: 'ALL', label: 'All regions' },
  ...ISLAND_GROUP_IDS.map((id) => ({
    id,
    label: ISLAND_GROUP_LABELS[id],
  })),
];

function normalizeSearch(value: string) {
  return value.trim().toLowerCase();
}

function matchesQuery(option: RegionPickerOption, query: string) {
  if (!query) return true;
  return (
    option.label.toLowerCase().includes(query) ||
    option.groupLabel.toLowerCase().includes(query) ||
    option.slug.replace(/-/g, ' ').includes(query)
  );
}

function RegionOptionRow({
  option,
  selected,
  onSelect,
  showGroup,
}: {
  option: RegionPickerOption;
  selected: boolean;
  onSelect: () => void;
  showGroup?: boolean;
}) {
  const isRegionWide = isEntireRegion(option.area as ServiceArea);

  return (
    <button
      type="button"
      onClick={onSelect}
      className={cn(
        'flex min-h-11 w-full items-center gap-3 rounded-xl px-3 py-3 text-left transition-colors sm:min-h-0 sm:py-2.5',
        selected
          ? 'bg-primary/10 ring-1 ring-primary/20'
          : 'hover:bg-slate-50 active:bg-slate-100'
      )}
    >
      <span
        className={cn(
          'flex h-5 w-5 shrink-0 items-center justify-center rounded-full border',
          selected ? 'border-primary bg-primary text-white' : 'border-slate-200 bg-white'
        )}
      >
        {selected && <Check className="h-3 w-3" strokeWidth={3} />}
      </span>
      <span className="min-w-0 flex-1">
        <span
          className={cn(
            'block truncate text-sm',
            selected ? 'font-semibold text-primary-dark' : 'font-medium text-slate-800'
          )}
        >
          {option.label}
        </span>
        {showGroup && (
          <span className="block truncate text-xs text-muted">{option.groupLabel}</span>
        )}
        {!showGroup && isRegionWide && (
          <span className="block text-xs text-muted">All cities in region</span>
        )}
      </span>
      {isRegionWide && !showGroup && (
        <span className="hidden shrink-0 rounded-md bg-slate-100 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-slate-500 sm:inline">
          Region
        </span>
      )}
    </button>
  );
}

interface RegionPickerModalProps {
  open: boolean;
  onClose: () => void;
  currentSlug: string;
  onSelect: (slug: string) => void;
}

export function RegionPickerModal({
  open,
  onClose,
  currentSlug,
  onSelect,
}: RegionPickerModalProps) {
  const [mounted, setMounted] = useState(false);
  const [search, setSearch] = useState('');
  const [islandFilter, setIslandFilter] = useState<IslandFilter>('ALL');
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  const searchInputRef = useRef<HTMLInputElement>(null);
  const titleId = useId();
  const searchId = useId();

  const query = normalizeSearch(search);
  const currentLabel = regionLabel(currentSlug);

  const searchResults = useMemo(
    () => (query ? ALL_OPTIONS.filter((o) => matchesQuery(o, query)) : []),
    [query]
  );

  const filteredAdminGroups = useMemo(() => {
    if (islandFilter === 'ALL') return ADMIN_GROUPS;
    return ADMIN_GROUPS.filter(
      (group) => ADMIN_REGION_ISLAND.get(group.id) === islandFilter
    );
  }, [islandFilter]);

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    if (!open) {
      setSearch('');
      setIslandFilter('ALL');
      return;
    }

    const containingGroup = ADMIN_GROUPS.find((g) =>
      g.options.some((o) => o.slug === currentSlug)
    );
    setExpandedGroups(
      containingGroup ? new Set([containingGroup.id]) : new Set()
    );

    if (containingGroup) {
      const island = ADMIN_REGION_ISLAND.get(containingGroup.id);
      if (island) setIslandFilter(island);
    }

    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKeyDown);
    document.body.classList.add('modal-open');
    document.body.style.overflow = 'hidden';

    const focusTimer = window.setTimeout(() => {
      if (window.matchMedia('(min-width: 640px)').matches) {
        searchInputRef.current?.focus();
      }
    }, 100);

    return () => {
      window.clearTimeout(focusTimer);
      document.removeEventListener('keydown', onKeyDown);
      document.body.classList.remove('modal-open');
      document.body.style.overflow = '';
    };
  }, [open, onClose, currentSlug]);

  const handleSelect = (slug: string) => {
    onSelect(slug);
    onClose();
  };

  const toggleGroup = (groupId: string) => {
    setExpandedGroups((prev) => {
      const next = new Set(prev);
      if (next.has(groupId)) next.delete(groupId);
      else next.add(groupId);
      return next;
    });
  };

  if (!open || !mounted) return null;

  return createPortal(
    <div className="fixed inset-0 z-[9999] flex items-end justify-center sm:items-center sm:p-4">
      <button
        type="button"
        className="absolute inset-0 bg-slate-900/50 backdrop-blur-[1px]"
        aria-label="Close area picker"
        onClick={onClose}
      />

      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
        className={cn(
          'relative z-[10000] flex w-full max-h-[min(92dvh,100dvh)] flex-col',
          'rounded-t-2xl border border-border bg-surface shadow-2xl',
          'pb-[env(safe-area-inset-bottom,0px)]',
          'sm:max-h-[min(85dvh,720px)] sm:max-w-lg sm:rounded-2xl sm:pb-0'
        )}
      >
        <div
          className="flex shrink-0 justify-center pt-2 sm:hidden"
          aria-hidden
        >
          <span className="h-1 w-10 rounded-full bg-slate-200" />
        </div>

        <div className="flex shrink-0 items-start justify-between gap-2 border-b border-border px-4 py-3 sm:gap-3 sm:px-5 sm:py-4">
          <div className="flex min-w-0 items-center gap-2.5 sm:gap-3">
            <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary sm:h-10 sm:w-10">
              <MapPin className="h-4 w-4 sm:h-5 sm:w-5" />
            </div>
            <div className="min-w-0">
              <h2 id={titleId} className="text-base font-bold text-slate-900">
                Choose your area
              </h2>
              <p className="truncate text-xs text-muted">
                Current:{' '}
                <span className="font-semibold text-slate-700">{currentLabel}</span>
              </p>
            </div>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="-mr-1 rounded-lg p-2.5 text-slate-500 hover:bg-slate-100 hover:text-slate-700 sm:mr-0 sm:p-2"
            aria-label="Close"
          >
            <X className="h-5 w-5" />
          </button>
        </div>

        <div className="sticky top-0 z-10 shrink-0 border-b border-border bg-surface px-4 py-3 sm:px-5">
          <label htmlFor={searchId} className="sr-only">
            Search areas
          </label>
          <div className="relative">
            <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
            <input
              ref={searchInputRef}
              id={searchId}
              type="search"
              enterKeyHint="search"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search city or region…"
              autoComplete="off"
              className="search-input-icon h-11 text-base sm:text-sm"
            />
          </div>
        </div>

        <div className="flex-1 overflow-y-auto overscroll-contain px-2 py-3 sm:px-4">
          {query ? (
            <div className="space-y-1">
              {searchResults.length === 0 ? (
                <p className="px-3 py-8 text-center text-sm text-muted">
                  No areas match &ldquo;{search.trim()}&rdquo;
                </p>
              ) : (
                <>
                  <p className="px-3 pb-1 text-xs text-muted">
                    {searchResults.length} result{searchResults.length === 1 ? '' : 's'}
                  </p>
                  {searchResults.map((option) => (
                    <RegionOptionRow
                      key={option.slug}
                      option={option}
                      selected={option.slug === currentSlug}
                      onSelect={() => handleSelect(option.slug)}
                      showGroup
                    />
                  ))}
                </>
              )}
            </div>
          ) : (
            <div className="space-y-4">
              <section>
                <div className="mb-2 flex items-center gap-1.5 px-2">
                  <Globe2 className="h-3.5 w-3.5 text-slate-400" />
                  <h3 className="text-[11px] font-semibold uppercase tracking-wide text-muted">
                    Quick picks
                  </h3>
                </div>
                <div className="-mx-1 flex gap-2 overflow-x-auto px-1 pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden sm:flex-wrap">
                  {QUICK_PICKS.map((option) => {
                    const selected = option.slug === currentSlug;
                    return (
                      <button
                        key={option.slug}
                        type="button"
                        onClick={() => handleSelect(option.slug)}
                        className={cn(
                          'inline-flex shrink-0 items-center gap-1.5 rounded-full px-4 py-2.5 text-xs font-semibold transition-colors sm:py-2',
                          selected
                            ? 'bg-primary text-white shadow-sm'
                            : 'bg-slate-100 text-slate-700 hover:bg-slate-200 active:bg-slate-200'
                        )}
                      >
                        {selected && <Check className="h-3 w-3" strokeWidth={3} />}
                        {option.label}
                      </button>
                    );
                  })}
                </div>
              </section>

              <section>
                <h3 className="mb-2 px-2 text-[11px] font-semibold uppercase tracking-wide text-muted">
                  Filter by island
                </h3>
                <div className="-mx-1 flex gap-2 overflow-x-auto px-1 pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
                  {ISLAND_FILTERS.map((filter) => {
                    const active = islandFilter === filter.id;
                    return (
                      <button
                        key={filter.id}
                        type="button"
                        onClick={() => setIslandFilter(filter.id)}
                        className={cn(
                          'shrink-0 rounded-full px-3.5 py-2 text-xs font-semibold transition-colors',
                          active
                            ? 'bg-slate-800 text-white'
                            : 'bg-slate-100 text-slate-600 hover:bg-slate-200 active:bg-slate-200'
                        )}
                      >
                        {filter.label}
                      </button>
                    );
                  })}
                </div>
              </section>

              <section className="space-y-1">
                <h3 className="px-2 text-[11px] font-semibold uppercase tracking-wide text-muted">
                  By region
                </h3>
                {filteredAdminGroups.length === 0 ? (
                  <p className="px-3 py-4 text-center text-sm text-muted">
                    No regions in this island group.
                  </p>
                ) : (
                  filteredAdminGroups.map((group) => {
                    const expanded = expandedGroups.has(group.id);
                    const selectedOption = group.options.find(
                      (o) => o.slug === currentSlug
                    );
                    const hasSelection = Boolean(selectedOption);

                    return (
                      <div
                        key={group.id}
                        className={cn(
                          'overflow-hidden rounded-xl border',
                          hasSelection
                            ? 'border-primary/20 bg-primary/[0.02]'
                            : 'border-transparent'
                        )}
                      >
                        <button
                          type="button"
                          onClick={() => toggleGroup(group.id)}
                          className="flex min-h-11 w-full items-center gap-2 px-3 py-3 text-left hover:bg-slate-50 active:bg-slate-100 sm:min-h-0 sm:py-2.5"
                        >
                          {expanded ? (
                            <ChevronDown className="h-4 w-4 shrink-0 text-slate-400" />
                          ) : (
                            <ChevronRight className="h-4 w-4 shrink-0 text-slate-400" />
                          )}
                          <span className="min-w-0 flex-1">
                            <span className="block truncate text-sm font-semibold text-slate-800">
                              {group.label}
                            </span>
                            {hasSelection && !expanded && selectedOption && (
                              <span className="block truncate text-xs font-medium text-primary">
                                {selectedOption.label}
                              </span>
                            )}
                          </span>
                          <span className="shrink-0 text-xs text-muted">
                            {group.options.length}
                          </span>
                        </button>

                        {expanded && (
                          <div className="space-y-0.5 border-t border-border/60 px-1 pb-1.5 pt-1">
                            {group.options.map((option) => (
                              <RegionOptionRow
                                key={option.slug}
                                option={{
                                  ...option,
                                  groupId: group.id,
                                  groupLabel: group.label,
                                }}
                                selected={option.slug === currentSlug}
                                onSelect={() => handleSelect(option.slug)}
                              />
                            ))}
                          </div>
                        )}
                      </div>
                    );
                  })
                )}
              </section>
            </div>
          )}
        </div>
      </div>
    </div>,
    document.body
  );
}
