import { JSX } from '@redneckz/uni-jsx';
import { useState } from '@redneckz/uni-jsx/lib/hooks';
import { useForm } from '../../hooks/useForm/useForm';
import { type ComponentType } from '../../model/ComponentType';
import { type TitleProps } from '../../model/HeadlineType';
import { type VNode } from '../../model/VNode';
import { ClientOnly } from '../../ui-kit/ClientOnly';
import { YandexMap } from '../../ui-kit/YandexMap/YandexMap';
import { style } from '../../utils/style';
import { FILTRATION_LABELS, FILTRATION_PREDICATES, INITIAL_FILTRATION_STATE } from './filters';
import { FiltrationForm } from './FiltrationForm';
import { type AtmsDef } from './OfficesAtmsMapContent';
import { type Atm, type Branch, type RemoteWorkplace } from './OfficesAtmsMapProps';
import { renderButtonsGroup } from './renderButtonsGroup';
import { renderDescriptionBlock } from './renderDescriptionBlock';
import { renderHeading } from './renderHeading';
import { useOfficesAtmsMapData } from './useOfficesAtmsMapData';
import { type BalloonContent } from './YandexMapProps';

const defaultEmptyFunction = () => void 0;

export type InitFilterState = Record<string, boolean>;

export interface OfficesAtmsMapLayoutProps<T> extends ComponentType, TitleProps {
  data?: T[];
  isLoad: boolean;
  remoteWorkplaces?: T[];
  renderCard?: (item: T, index: number) => VNode;
  renderRemoteWorkplaceCard?: (item: T, index: number) => VNode;
  getBalloon?: (item: T) => BalloonContent;
  getBalloonRemoteWorkplaces?: (item: T) => BalloonContent;
  initFilterState?: InitFilterState;
  descriptionData?: AtmsDef;
}

const filtersVisibleStyles = (activeButton: string) =>
  activeButton === 'all' ? 'block' : 'hidden';

export const OfficesAtmsMapLayout = JSX<OfficesAtmsMapLayoutProps<Branch | Atm | RemoteWorkplace>>(
  ({
    className,
    data = [],
    isLoad,
    remoteWorkplaces = [],
    renderCard = defaultEmptyFunction,
    renderRemoteWorkplaceCard = defaultEmptyFunction,
    getBalloon = defaultEmptyFunction,
    initFilterState = INITIAL_FILTRATION_STATE,
    getBalloonRemoteWorkplaces = defaultEmptyFunction,
    descriptionData,
    title,
  }) => {
    const onlyOffice = title?.includes('Офис');
    const [filtrationState, { field, reset }] = useForm(initFilterState);

    const { filteredItems, points, filteredRemoteWorkplaces, lengthItems } = useOfficesAtmsMapData({
      data,
      remoteWorkplaces,
      filtrationState,
      getBalloon,
      getBalloonRemoteWorkplaces,
    });

    const [activeButton, setActiveButton] = useState('all');

    return (
      <div className={style('space-y-1', className)}>
        <div className="bg-white">
          <div className="p-3xl pb-0 grid gap-xl">
            {renderHeading(title, lengthItems)}
            {descriptionData ? renderDescriptionBlock(descriptionData) : null}
            {onlyOffice && renderButtonsGroup(data, activeButton, setActiveButton)}
            <div className={style('pb-3xl', filtersVisibleStyles(activeButton))}>
              <FiltrationForm
                filters={getFiltersWithNonEmptyData([...data, ...remoteWorkplaces])}
                field={{ field, reset }}
                onlyOffice={onlyOffice}
                labels={FILTRATION_LABELS}
              />
            </div>
          </div>
          <div className="h-[600px]">
            <ClientOnly>
              <YandexMap
                points={points}
                isLoad={isLoad}
                className="h-full"
                showSearchField={true}
              />
            </ClientOnly>
          </div>
        </div>
        <ClientOnly>
          {filteredItems.map(renderCard)}
          {filteredRemoteWorkplaces.map(renderRemoteWorkplaceCard)}
        </ClientOnly>
      </div>
    );
  },
);

export const getFiltersWithNonEmptyData = (data: (Branch | Atm | RemoteWorkplace)[]) =>
  Object.keys(INITIAL_FILTRATION_STATE).filter(
    (_) => data.filter((item) => FILTRATION_PREDICATES[_](item)).length,
  );
