/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';

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

import { X } from 'lucide-react';
import { Control, useController } from 'react-hook-form';

import CreatorAvatar from '@/components/creators/CreatorAvatar';
import { CREATOR_SEARCH_MIN_QUERY_LENGTH } from '@/components/creators/creatorSearchConfig';
import { Input } from '@/components/ui/input';
import { useCreatorSearch } from '@/hooks/useCreatorSearch';
import { cn } from '@/lib/utils';

import { FieldWrapper } from './FieldWrapper';

interface Creator {
  id: number;
  nev: string;
  szakma?: string;
  profilkep: { key: string };
}

interface CreatorMultiSelectProps {
  control: Control<any>;
  name: string;
  label: string;
  required?: boolean;
  requiredNote?: string;
  helper?: string;
  placeholder?: string;
  // to store/retrieve creator objects
  creatorObjectsName?: string;
}

export const CreatorMultiSelect: React.FC<CreatorMultiSelectProps> = ({
  control,
  name,
  label,
  required,
  requiredNote,
  helper,
  placeholder,
  creatorObjectsName,
}) => {
  const {
    field,
    fieldState: { error },
  } = useController({ control, name });

  const creatorObjectsField = useController({
    control,
    name: creatorObjectsName || `${name}Objects`,
  });

  const [query, setQuery] = useState('');
  const { results, loading, isQueryTooShort } = useCreatorSearch<Creator>({
    query,
    minQueryLength: CREATOR_SEARCH_MIN_QUERY_LENGTH,
    debounceMs: 300,
  });

  const selectedObjects = useMemo<Creator[]>(
    () => (Array.isArray(creatorObjectsField.field.value) ? creatorObjectsField.field.value : []),
    [creatorObjectsField.field.value]
  );

  useEffect(() => {
    const selectedIds: number[] = Array.isArray(field.value) ? field.value : [];
    if (selectedIds.length === 0 || results.length === 0) return;

    const freshObjects = results.filter((creator) => selectedIds.includes(creator.id));
    if (freshObjects.length === 0) return;

    const updatedObjects = [
      ...selectedObjects.filter((creator) => selectedIds.includes(creator.id)),
      ...freshObjects.filter((creator) => !selectedObjects.some((prev) => prev.id === creator.id)),
    ];

    const currentIds = selectedObjects.map((creator) => creator.id).sort((a, b) => a - b);
    const updatedIds = updatedObjects.map((creator) => creator.id).sort((a, b) => a - b);

    const isSameSelection =
      currentIds.length === updatedIds.length &&
      currentIds.every((id, index) => id === updatedIds[index]);

    if (isSameSelection) return;
    creatorObjectsField.field.onChange(updatedObjects);
  }, [creatorObjectsField.field, field.value, results, selectedObjects]);

  const addCreator = (creator: Creator) => {
    const selectedIds: number[] = Array.isArray(field.value) ? field.value : [];
    if (!selectedIds.includes(creator.id)) {
      field.onChange([...selectedIds, creator.id]);

      const updatedObjects = selectedObjects.some((prev) => prev.id === creator.id)
        ? selectedObjects
        : [...selectedObjects, creator];

      creatorObjectsField.field.onChange(updatedObjects);
    }
    setQuery('');
  };

  const removeCreator = (id: number) => {
    const selectedIds: number[] = Array.isArray(field.value) ? field.value : [];
    field.onChange(selectedIds.filter((creatorId) => creatorId !== id));
    creatorObjectsField.field.onChange(selectedObjects.filter((creator) => creator.id !== id));
  };

  const findCreator = (id: number) =>
    selectedObjects.find((creator) => creator.id === id) ||
    results.find((creator) => creator.id === id);

  return (
    <FieldWrapper
      label={label}
      required={required}
      requiredNote={requiredNote}
      helper={helper}
      error={error?.message}
    >
      {Array.isArray(field.value) && field.value.length > 0 ? (
        <div className="creator-chips mb-2 flex flex-wrap gap-2">
          {field.value.map((id: number) => {
            const creator = findCreator(id);

            return (
              <div
                key={id}
                className="creator-chip mb-2 flex items-center gap-2 bg-mma-blue px-3 py-2 text-sm font-semibold text-white"
              >
                <span>{creator?.nev}</span>
                <button
                  type="button"
                  onClick={() => removeCreator(id)}
                  className="hover:opacity-70"
                >
                  <X className="h-4 w-4" />
                </button>
              </div>
            );
          })}
        </div>
      ) : null}

      <Input
        placeholder={placeholder}
        value={query}
        onChange={(event) => setQuery(event.target.value)}
        className="creator-input"
      />

      {!isQueryTooShort ? (
        <div className="creator-results mt-2 max-h-64 overflow-auto border border-mma-blue/10 bg-white">
          {loading ? (
            <div className="p-3 text-sm text-gray-500">Keresés...</div>
          ) : results.length === 0 ? (
            <div className="p-3 text-sm text-gray-500">Nincs találat.</div>
          ) : (
            results.map((creator) => (
              <div
                key={creator.id}
                onClick={() => addCreator(creator)}
                className={cn(
                  'creator-result-item flex cursor-pointer items-center gap-2 px-3 py-2 hover:bg-mma-cyan/10',
                  Array.isArray(field.value) && field.value.includes(creator.id) && 'bg-mma-cyan/20'
                )}
              >
                <CreatorAvatar
                  imageKey={creator.profilkep?.key}
                  name={creator.nev}
                  width={48}
                  height={48}
                  imageClassName="h-12 w-12 rounded-full"
                  wrapperClassName="h-12 w-12 rounded-full"
                />
                <div>
                  <div>{creator.nev}</div>
                  <div className="text-xs text-gray-500">{creator.szakma}</div>
                </div>
              </div>
            ))
          )}
        </div>
      ) : null}
    </FieldWrapper>
  );
};
