import React, { useEffect, useRef, useState } from 'react';

import { useAppStateContext } from '../../context/user.data.context';
import { inlineGenerateFromContentCheck } from '../../service/content-generator/content-generator.service';
import type { InlineGenerateMode } from '../../service/content-generator/content-generator.interface';
import { LANGUAGE_OPTIONS } from '../../data/locales';
import {
  CREATIVITY_OPTIONS,
  FAQ_COUNT_OPTIONS,
} from '../../lib/catalog-action-options';

import InlineResultCard from './InlineResultCard';

const COPY: Record<
  'gap' | 'faq',
  { title: string; description: string; placeholder: string }
> = {
  gap: {
    title: 'Add missing content',
    description:
      'Generates an improved title plus the content the description is missing. Steer it with an optional instruction, then preview and copy.',
    placeholder:
      "Optional: which details matter most (dimensions, materials, what's in the box)...",
  },
  faq: {
    title: 'Generate FAQ',
    description:
      'Writes the questions shoppers ask, answered from the description. Steer it with an optional instruction, then preview and copy.',
    placeholder: 'Optional: topics to focus on (fit, care, compatibility)...',
  },
};

const SELECT_CLASS =
  'block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900';
const TEXTAREA_CLASS =
  'block w-full rounded-md border-gray-300 px-3 py-2 text-sm placeholder:text-gray-400 focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900';

/** Props for {@link ProductActionModal}. */
interface ProductActionModalProps {
  open: boolean;
  onOpenChange: (next: boolean) => void;
  /** ``gap`` (Add missing) or ``faq``. */
  mode: 'gap' | 'faq';
  jobId: string;
  sku: string;
  productName: string;
  language: string;
  /** Audit's title issues, shown under "What's missing" for gap. */
  titleIssues: string[];
  /** Audit's description issues, shown under "What's missing" for gap. */
  descriptionIssues: string[];
}

/**
 * Per-product modal for the Add-missing / FAQ actions. Collects an optional
 * instruction, language, creativity (and FAQ count), generates synchronously
 * against the inline endpoint, and renders the preview right in the modal with
 * Copy buttons. Closes on Esc / backdrop click while idle.
 *
 * @param {ProductActionModalProps} props - Modal config.
 * @return {JSX.Element | null} The modal, or null while closed.
 */
const ProductActionModal = ({
  open,
  onOpenChange,
  mode,
  jobId,
  sku,
  productName,
  language,
  titleIssues,
  descriptionIssues,
}: ProductActionModalProps): JSX.Element | null => {
  const { clientId } = useAppStateContext();

  const [instruction, setInstruction] = useState<string>('');
  const [titleInstruction, setTitleInstruction] = useState<string>('');
  const [descriptionInstruction, setDescriptionInstruction] =
    useState<string>('');
  const [lang, setLang] = useState<string>(language);
  const [temperature, setTemperature] = useState<string>('0.7');
  const [faqCount, setFaqCount] = useState<string>('3');
  const [generating, setGenerating] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const [result, setResult] = useState<{
    mode: InlineGenerateMode;
    content: string;
  } | null>(null);
  const resultRef = useRef<HTMLDivElement>(null);

  // Reset the previous result when switching action (gap <-> faq) or product so
  // the panel below never shows stale content from the other mode.
  useEffect(() => {
    setResult(null);
    setError(null);
  }, [mode, sku]);

  // Keep the language picker in sync with the audit's detected language.
  useEffect(() => {
    setLang(language);
  }, [language]);

  useEffect(() => {
    if (!open) return undefined;
    const handleKey = (event: KeyboardEvent): void => {
      if (event.key === 'Escape' && !generating) onOpenChange(false);
    };
    window.addEventListener('keydown', handleKey);

    return () => window.removeEventListener('keydown', handleKey);
  }, [open, generating, onOpenChange]);

  useEffect(() => {
    if (result) {
      resultRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }, [result]);

  const handleGenerate = async (): Promise<void> => {
    if (!clientId || generating) return;
    setGenerating(true);
    setError(null);
    setResult(null);
    try {
      const trimmedTitle = titleInstruction.trim();
      const trimmedDescription = descriptionInstruction.trim();
      const trimmedCustom = instruction.trim();
      const response = await inlineGenerateFromContentCheck(
        jobId,
        sku,
        {
          mode,
          title_prompt:
            mode === 'gap' && trimmedTitle ? trimmedTitle : undefined,
          description_prompt:
            mode === 'gap' && trimmedDescription
              ? trimmedDescription
              : undefined,
          custom_prompt:
            mode === 'faq' && trimmedCustom ? trimmedCustom : undefined,
          language: lang || undefined,
          temperature: Number(temperature),
          faq_count: mode === 'faq' ? Number(faqCount) : undefined,
        },
        clientId
      );
      if (response?.errors || !response?.data?.content) {
        setError(response?.message ?? 'Could not generate content.');

        return;
      }
      setResult({ mode, content: response.data.content });
    } catch {
      setError('Could not generate content. Try again.');
    } finally {
      setGenerating(false);
    }
  };

  if (!open) return null;

  const copy = COPY[mode];

  return (
    <div className="fixed inset-0 z-[1000] flex items-center justify-center p-4">
      <div
        className="absolute inset-0 bg-black/40"
        onClick={() => {
          if (!generating) onOpenChange(false);
        }}
      />
      <div
        role="dialog"
        aria-modal="true"
        aria-label={copy.title}
        className="relative z-10 max-h-[88vh] w-full max-w-3xl overflow-y-auto rounded-xl bg-white p-6 shadow-xl"
      >
        <div className="min-w-0">
          <h3 className="text-base font-semibold text-gray-900">
            {copy.title}
          </h3>
          <p className="mt-1 text-sm font-medium text-gray-900">
            {productName || sku}
          </p>
          <p className="mt-1 text-sm text-gray-500">{copy.description}</p>
        </div>

        <div className="mt-5 min-w-0 space-y-4">
          {mode === 'gap' &&
            (titleIssues.length > 0 || descriptionIssues.length > 0) && (
              <div className="space-y-3 rounded-md border border-gray-200 bg-gray-50 p-3">
                <p className="text-[11px] font-semibold uppercase tracking-wider text-gray-500">
                  What&apos;s missing
                </p>
                {titleIssues.length > 0 && (
                  <div className="space-y-1">
                    <p className="text-[11px] font-medium text-gray-500">
                      Title
                    </p>
                    <ul className="space-y-1 text-xs text-gray-900">
                      {titleIssues.map((issue, issueIndex) => (
                        <li key={issueIndex} className="leading-relaxed">
                          <span className="text-gray-400">·</span> {issue}
                        </li>
                      ))}
                    </ul>
                  </div>
                )}
                {descriptionIssues.length > 0 && (
                  <div className="space-y-1">
                    <p className="text-[11px] font-medium text-gray-500">
                      Description
                    </p>
                    <ul className="space-y-1 text-xs text-gray-900">
                      {descriptionIssues.map((issue, issueIndex) => (
                        <li key={issueIndex} className="leading-relaxed">
                          <span className="text-gray-400">·</span> {issue}
                        </li>
                      ))}
                    </ul>
                  </div>
                )}
              </div>
            )}

          {mode === 'faq' && (
            <div className="space-y-1.5">
              <label className="block text-sm font-medium text-gray-900">
                How many questions
              </label>
              <select
                value={faqCount}
                onChange={event => setFaqCount(event.target.value)}
                className={`${SELECT_CLASS} sm:w-40`}
              >
                {FAQ_COUNT_OPTIONS.map(count => (
                  <option key={count} value={count}>
                    {count}
                  </option>
                ))}
              </select>
            </div>
          )}

          {mode === 'gap' ? (
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              <div className="space-y-1.5">
                <label className="block text-sm font-medium text-gray-900">
                  Title instruction (optional)
                </label>
                <textarea
                  value={titleInstruction}
                  onChange={event => setTitleInstruction(event.target.value)}
                  placeholder="Optional: how the title should read..."
                  rows={2}
                  maxLength={3500}
                  className={TEXTAREA_CLASS}
                />
              </div>
              <div className="space-y-1.5">
                <label className="block text-sm font-medium text-gray-900">
                  Description instruction (optional)
                </label>
                <textarea
                  value={descriptionInstruction}
                  onChange={event =>
                    setDescriptionInstruction(event.target.value)
                  }
                  placeholder={copy.placeholder}
                  rows={2}
                  maxLength={3500}
                  className={TEXTAREA_CLASS}
                />
              </div>
            </div>
          ) : (
            <div className="space-y-1.5">
              <label className="block text-sm font-medium text-gray-900">
                Custom instruction (optional)
              </label>
              <textarea
                value={instruction}
                onChange={event => setInstruction(event.target.value)}
                placeholder={copy.placeholder}
                rows={2}
                maxLength={3500}
                className={TEXTAREA_CLASS}
              />
            </div>
          )}

          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
            <div className="space-y-1.5">
              <label className="block text-sm font-medium text-gray-900">
                Language
              </label>
              <select
                value={lang}
                onChange={event => setLang(event.target.value)}
                className={SELECT_CLASS}
              >
                {LANGUAGE_OPTIONS.map(option => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>
            <div className="space-y-1.5">
              <label className="block text-sm font-medium text-gray-900">
                Creativity
              </label>
              <select
                value={temperature}
                onChange={event => setTemperature(event.target.value)}
                className={SELECT_CLASS}
              >
                {CREATIVITY_OPTIONS.map(option => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>
          </div>

          <div className="flex items-center justify-end gap-2">
            <button
              type="button"
              onClick={() => onOpenChange(false)}
              disabled={generating}
              className="rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50"
            >
              Close
            </button>
            <button
              type="button"
              onClick={handleGenerate}
              disabled={generating}
              className="inline-flex items-center gap-1.5 rounded-md bg-[#B7007C] px-4 py-2 text-sm font-semibold text-white hover:bg-[#900063] disabled:opacity-60"
            >
              {generating ? 'Generating…' : result ? 'Regenerate' : 'Generate'}
            </button>
          </div>

          {error && (
            <p className="text-sm text-red-600" role="alert">
              {error}
            </p>
          )}

          {result && (
            <div ref={resultRef} className="border-t border-gray-200 pt-4">
              {mode === 'gap' && (
                <p className="mb-2 text-xs text-gray-500">
                  Suggested update:{' '}
                  <span className="rounded bg-emerald-100 px-1 text-emerald-800">
                    additions
                  </span>{' '}
                  and{' '}
                  <span className="rounded bg-red-100 px-1 text-red-700 line-through">
                    removals
                  </span>
                  . Copy HTML gives the final clean version.
                </p>
              )}
              <InlineResultCard mode={result.mode} content={result.content} />
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default ProductActionModal;
