import React, { useEffect, useRef, useState } from 'react';
import { Select } from 'antd';
import useDebounce from '@/hooks/useDebounce';
import { getProjects } from '../service';

export interface ProjectOption {
  id: number;
  name: string;
  city_id: number | null;
}

interface ProjectSelectProps {
  cityId?: number;
  value?: number;
  valueLabel?: string;
  disabled?: boolean;
  onSelect: (project: ProjectOption) => void;
}

const PAGE_SIZE = 10;

/*
  The SMS rotation's "campaign" picker — a project, not an ad-platform
  campaign. A city can have many active projects, so this loads them 10 at a
  time via scroll, same pagination pattern as LaunchMultiSelect/CampaignSelect.
 */
const ProjectSelect: React.FC<ProjectSelectProps> = ({ cityId, value, valueLabel, disabled, onSelect }) => {
  const [projects, setProjects] = useState<ProjectOption[]>([]);
  const [loading, setLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(false);
  const loadMoreLock = useRef(false);

  const debouncedSearch = useDebounce(searchQuery, 400);

  const fetchProjects = (search: string, nextPage: number): void => {
    if (!cityId) return;
    setLoading(true);
    getProjects({ city_id: cityId, search, page: nextPage, pageSize: PAGE_SIZE })
      .then((res: any) => {
        const body = res?.data || {};
        const list: ProjectOption[] = body.data || [];
        setPage(body.page || nextPage);
        setHasMore(!!body.hasMore);
        setProjects((prev) => (nextPage === 1 ? list : [...prev, ...list]));
      })
      .finally(() => {
        setLoading(false);
        loadMoreLock.current = false;
      });
  };

  useEffect(() => {
    if (!cityId) {
      setProjects([]);
      return;
    }
    fetchProjects(debouncedSearch, 1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cityId, debouncedSearch]);

  const handlePopupScroll = (e: React.UIEvent<HTMLDivElement>): void => {
    const { currentTarget } = e;
    const reachedBottom = currentTarget.scrollTop + currentTarget.clientHeight >= currentTarget.scrollHeight - 5;
    if (reachedBottom && hasMore && !loading && !loadMoreLock.current) {
      loadMoreLock.current = true;
      fetchProjects(searchQuery, page + 1);
    }
  };

  // The saved/selected project may not be on the currently loaded page — keep
  // its name visible via valueLabel until it's actually seen in a fetched page.
  const loadedIds = new Set(projects.map((p) => p.id));
  const options = [
    ...projects,
    ...(value !== undefined && !loadedIds.has(value) ? [{ id: value, name: valueLabel || `#${value}`, city_id: cityId ?? null }] : []),
  ].map((p) => ({ value: p.id, label: p.name }));

  return (
    <Select
      className="block mt-1"
      style={{ width: '100%' }}
      showSearch
      loading={loading}
      disabled={disabled || !cityId}
      placeholder={cityId ? 'Select project' : 'Select a city first'}
      value={value}
      filterOption={false}
      onSearch={setSearchQuery}
      onPopupScroll={handlePopupScroll}
      onChange={(id: number) => {
        const project = projects.find((p) => p.id === id);
        if (project) onSelect(project);
      }}
      options={options}
    />
  );
};

export default ProjectSelect;
