import { useCallback, useMemo } from 'react';

import { MenuTrigger } from '../../../components/Menu/components/MenuTrigger/MenuTrigger';
import { useTranslation } from '../../../core/hooks/useTranslation';
import { SelectField } from '../../../form/SelectField/SelectField';
import { TestIdProps } from '../../../types';
import { assertEmptyObject } from '../../../utils/assertEmptyObject';
import { HeaderCompany } from '../types';

export interface CompanySelectProps extends TestIdProps {
  /** List of available companies */
  companies: HeaderCompany[];
  /** ID of selected company */
  currentCompanyId: string;
  /** Function that will be invoked when current company is changed */
  onCurrentCompanyIdChange?: (companyId: string) => void;
}

export function CompanySelect(props: CompanySelectProps) {
  const { companies, currentCompanyId, onCurrentCompanyIdChange, testId, ...rest } = props;
  assertEmptyObject(rest);

  const { t } = useTranslation();

  const options = useMemo(() => {
    return companies.map((company) => ({ label: company.name, value: company.id }));
  }, [companies]);

  const currentCompany = useMemo(
    () => companies.find((company) => company.id === currentCompanyId),
    [companies, currentCompanyId],
  );

  if (!currentCompany) {
    throw new Error(`Not found company with id "${currentCompanyId}".`);
  }

  const handleChange = useCallback(
    (companyId: string | null) => {
      /* istanbul ignore next */
      if (!onCurrentCompanyIdChange) {
        return;
      }

      /* istanbul ignore next */
      if (companyId === null) {
        throw new Error("The company id can't be null");
      }

      onCurrentCompanyIdChange(companyId);
    },
    [onCurrentCompanyIdChange],
  );

  return (
    <SelectField
      ariaLabel={t('ui.header.selectedCompany')}
      onChange={handleChange}
      options={options}
      testId={testId}
      trigger={<MenuTrigger>{currentCompany.name}</MenuTrigger>}
      value={currentCompanyId}
    />
  );
}
