import {useTrans} from '@ui/i18n/use-trans';
import React, {useState, useEffect} from 'react';
import {useFormContext, useController} from 'react-hook-form';
import {UpdateChannelPayload} from '@common/admin/channels/requests/use-update-channel';
import {useValueLists} from '@common/http/value-lists';
import {FormSelect} from '@ui/forms/select/select';
import {message} from '@ui/i18n/message';
import {Trans} from '@ui/i18n/trans';
import {Item} from '@ui/forms/listbox/item';
import {ChannelContentConfig} from '@common/admin/channels/channel-editor/channel-content-config';
import {ChannelRestrictionField} from '@common/admin/channels/channel-editor/controls/channel-restriction-field';
import {GENRE_MODEL} from '@app/web-player/genres/genre';
import {FormChipField} from '@ui/forms/input-field/chip-field/form-chip-field';
import {useNormalizedModels} from '@common/ui/normalized-model/use-normalized-models';
import {NormalizedModel} from '@ui/types/normalized-model';

interface Props {
  className?: string;
  config: ChannelContentConfig;
}
export function AppChannelRestrictionField({className, config}: Props) {
  const {watch} = useFormContext<UpdateChannelPayload>();
  const contentType = watch('config.contentType');

  if (contentType !== 'listAll') return null;

  return (
    <ChannelRestrictionField config={config} className={className}>
      <RestrictionModelField config={config} />
    </ChannelRestrictionField>
  );
}

interface RestrictionModelFieldProps {
  config: ChannelContentConfig;
}
function RestrictionModelField({config}: RestrictionModelFieldProps) {
  const {trans} = useTrans();
  const [searchValue, setSearchValue] = useState('');
  const {watch, setValue} = useFormContext<UpdateChannelPayload>();
  const selectedId = watch('config.restrictionModelId');
  const query = useValueLists(['genres'], {
    searchQuery: searchValue,
    selectedValue: selectedId,
    type: watch('config.autoUpdateProvider'),
  });

  const selectedRestriction = watch(
    'config.restriction',
  ) as keyof typeof config.restrictions;

  if (!selectedRestriction) return null;

  const options = {
    [GENRE_MODEL]: query.data?.genres,
  } as Record<string, {value: string; name: string}[]>;
  const restrictionLabel = config.restrictions[selectedRestriction].label;

  // For genre restrictions, use custom chip field that handles ID conversion
  const isGenreRestriction = selectedRestriction === 'genre';

  if (isGenreRestriction) {
    return (
      <ChannelGenreChipField
        label={
          <Trans
            message=":restriction name"
            values={{restriction: trans(restrictionLabel)}}
          />
        }
        placeholder={trans(message('+Add genre'))}
        className="w-full flex-auto"
      />
    );
  }

  return (
    <FormSelect
      className="w-full flex-auto"
      name="config.restrictionModelId"
      selectionMode="single"
      showSearchField
      searchPlaceholder={trans(message('Search...'))}
      isAsync={false}
      isLoading={false}
      inputValue={searchValue}
      onInputValueChange={setSearchValue}
      label={
        <Trans
          message=":restriction name"
          values={{restriction: trans(restrictionLabel)}}
        />
      }
      onSelectionChange={(value: any) => {
        setValue('config.restrictionModelId', value);
      }}
    >
      <Item value="urlParam">
        <Trans message="Dynamic (from url)" />
      </Item>
      {options[selectedRestriction]?.map(option => (
        <Item key={option.value} value={option.value}>
          <Trans message={option.name} />
        </Item>
      ))}
    </FormSelect>
  );
}

interface ChannelGenreChipFieldProps {
  label?: React.ReactNode;
  placeholder?: string;
  className?: string;
}

function ChannelGenreChipField({label, placeholder, className}: ChannelGenreChipFieldProps) {
  const [inputValue, setInputValue] = useState('');
  const {setValue, watch} = useFormContext<UpdateChannelPayload>();
  const selectedGenreIds = watch('config.restrictionModelId');

  // Always work with string ids for comparison
  const currentIds: string[] = Array.isArray(selectedGenreIds)
    ? selectedGenreIds.map(id => String(id))
    : (selectedGenreIds && selectedGenreIds !== 'urlParam' ? [String(selectedGenreIds)] : []);

  // Use useValueLists to get all genres
  const {data: genresData, isLoading} = useValueLists(['genres'], {
    searchQuery: inputValue,
    selectedValue: currentIds,
  });

  // Deduplicate genres by id (string)
  const seen = new Set();
  const availableGenres: NormalizedModel[] = (genresData?.genres || [])
    .filter(genre => {
      const id = String(genre.value);
      if (seen.has(id)) return false;
      seen.add(id);
      return true;
    })
    .map(genre => ({
      id: String(genre.value),
      name: genre.name,
      model_type: GENRE_MODEL,
    }));

  // Only show chips for unique selected ids
  const selectedGenres = availableGenres.filter(genre =>
    currentIds.includes(String(genre.id))
  );

  // Handle add/remove
  const handleChange = (newValue: any[]) => {
    // Only keep unique ids
    const uniqueIds = Array.from(new Set(newValue.map(item => String(item.id))));
    setValue('config.restrictionModelId', uniqueIds as any);
  };

  return (
    <FormChipField
      className={className}
      name="tempGenreField"
      label={label}
      isAsync
      inputValue={inputValue}
      onInputValueChange={setInputValue}
      suggestions={availableGenres}
      placeholder={placeholder}
      isLoading={isLoading}
      allowCustomValue={false}
      value={selectedGenres}
      onChange={handleChange}
    >
      {availableGenres.map(result => (
        <Item
          value={result}
          key={result.id}
          isDisabled={currentIds.includes(String(result.id))}
          startIcon={
            result.image ? (
              <img
                className="h-24 w-24 rounded-full object-cover"
                src={result.image}
                alt=""
              />
            ) : undefined
          }
        >
          {result.name}
        </Item>
      ))}
    </FormChipField>
  );
}
