import React, { useState, useEffect } from 'react';
import Select, {
  components,
  type DropdownIndicatorProps,
  type ControlProps,
  type GroupBase,
  type SingleValue,
} from 'react-select';
import { post } from '../utilities/fetcher.js';
import { RotateCw } from 'lucide-react';
import Lightbulb from '../../assets/lightbulb.svg?react';
import Button from '../components/Button.js';
import useSWRImmutable from 'swr/immutable';
import './CreateMetaDescription.css';
import Loading from '../components/Loading.js';
import type { OptionType } from '../utilities/types.js';
import FormIndicator from './FormIndicator.js';
import { useEffectEvent } from '../hooks/useEffectEvent.js';

export default function CreateMetaDescription({
  accountId,
  draftId,
  text = '',
  setText = (_) => {},
}: {
  accountId: string;
  draftId: string;
  text?: string;
  setText?: (_: string) => void;
}) {
  const [menuIsOpen, setMenuIsOpen] = useState(false);
  const onMenuOpen = useEffectEvent(() => {
    mutate(undefined, { revalidate: true });
  });

  const minRecommendedCharacters = 120;
  const maxRecommendedCharacters = 159;

  useEffect(() => {
    if (menuIsOpen) {
      onMenuOpen();
    }
  }, [menuIsOpen]);

  const { data: dataValidateKeywords, mutate: mutateValidateKeywords } = useSWRImmutable(
    text && draftId
      ? [
          `/conductor/proxy/v3/${accountId}/drafts/${draftId}/validate-keywords/content-guidance`,
          {
            metaDescription: text,
          },
        ]
      : null,
    post,
    { fallbackData: [] },
  );
  // Debounce and call mutate when value stabilises.
  useEffect(() => {
    if (text) {
      const timer = setTimeout(() => {
        mutateValidateKeywords();
      }, 500); // Wait 500ms after user stops typing

      return () => {
        clearTimeout(timer);
      };
    }
  }, [text, mutateValidateKeywords]);
  const metaDescriptionAnalysis = dataValidateKeywords.filter(
    (item: { type: string }) => item.type === 'HTML_META_DESCRIPTION_COMMON',
  );
  const topicValid = !!metaDescriptionAnalysis.filter((item: { details: boolean }) =>
    Object.values(item.details).includes(true),
  ).length;

  const { data, isLoading, mutate } = useSWRImmutable(
    [
      `/conductor/proxy/v3/meta-description/content-generation?draft_id=${draftId}`,
      {
        suggested_meta_descriptions_count: 3,
        min_characters_per_meta_description: minRecommendedCharacters,
        max_characters_per_meta_description: maxRecommendedCharacters,
      },
    ],
    post,
    { fallbackData: { descriptions: [] as string[] } },
  );
  const options =
    data?.descriptions?.map((metaDescription: string) => ({
      value: metaDescription,
      label: metaDescription,
    })) || [];

  const DropdownIndicator = (
    props: DropdownIndicatorProps<OptionType, boolean, GroupBase<OptionType>>,
  ) => {
    return (
      <components.DropdownIndicator {...props}>
        <Lightbulb />
      </components.DropdownIndicator>
    );
  };

  const Control = ({ children, ...props }: ControlProps<OptionType>) => {
    if (menuIsOpen) {
      return;
    }
    return <components.Control {...props}>{children}</components.Control>;
  };

  return (
    <div className="create-meta-description">
      <div className="create-meta-description__header">
        <label className="create-meta-description__label" htmlFor="meta-description">
          Meta description
        </label>
        <div className="create-meta-description__topic">
          <FormIndicator value={metaDescriptionAnalysis.length ? text : ''} valid={topicValid} />
          Topic
        </div>
        <div
          className="create-meta-description__length"
          title={
            text.length >= minRecommendedCharacters && text.length <= maxRecommendedCharacters
              ? ''
              : 'Meta description falls short of length guidelines.\n' +
                '\n' +
                `Keep your meta description between ${minRecommendedCharacters}-${maxRecommendedCharacters} characters.`
          }
        >
          <FormIndicator
            value={text}
            valid={
              text.length >= minRecommendedCharacters && text.length <= maxRecommendedCharacters
            }
          />
          Length
        </div>
      </div>
      <div
        className={`create-meta-description__form ${
          menuIsOpen ? 'create-meta-description__form--is-open' : ''
        }`}
      >
        <Select<OptionType, false>
          options={options}
          isLoading={isLoading}
          loadingMessage={() => <Loading />}
          onChange={(selected: SingleValue<OptionType>) => setText(selected ? selected.value : '')}
          isSearchable={false}
          components={{ DropdownIndicator, Control }}
          menuIsOpen={menuIsOpen}
          onMenuOpen={() => setMenuIsOpen(true)}
          onMenuClose={() => setMenuIsOpen(false)}
          className="create-meta-description__select"
          classNamePrefix="create-meta-description"
        />

        {!menuIsOpen && (
          <textarea
            data-testid="meta-description-textarea"
            className="create-meta-description__textarea"
            value={text}
            onChange={(e) => setText(e.target.value)}
            name="meta-description"
            aria-label="Meta description"
            rows={3}
          />
        )}
        {menuIsOpen && (
          <div className="create-meta-description__menu-footer">
            <button
              data-testid="reload-meta-descriptions"
              className="create-meta-description__reload"
              disabled={isLoading}
              onClick={() => mutate(undefined, { revalidate: true })}
            >
              <RotateCw />
            </button>
            <Button
              disabled={isLoading}
              variant="surface"
              size="1"
              onClick={() => setMenuIsOpen(false)}
            >
              Close
            </Button>
          </div>
        )}
      </div>
    </div>
  );
}
