import React, { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { HiSparkles as Sparkles } from 'react-icons/hi';
import {
  FaCheck as Check,
  FaFileAlt as FileText,
  FaPencilAlt as PenLine,
  FaRegCopy as Copy,
} from 'react-icons/fa';

import { prepareProductSuggestionForGap } from '../../service/agent-analytics/agent-analytics.service';
import type {
  IAgentGap,
  IAgentGapProductSuggestionResponse,
} from '../../service/agent-analytics/agent-analytics.interface';

/** Server-enforced max length of the "suggest more" hint - matches the
 *  ``extra_prompt`` cap on ``AgentGapProductSuggestionRequest`` in
 *  recomaze-agent. */
const SUGGEST_MORE_MAX_LENGTH: number = 600;

interface GapProductSuggestionModalProps {
  /** Gap row the merchant clicked "Suggest snippet" on. */
  gap: IAgentGap;
  /** Initial draft returned by the parent's first call to the endpoint. */
  initial: IAgentGapProductSuggestionResponse;
  /** Called when the merchant cancels or closes the modal. */
  onClose: () => void;
}

/**
 * Modal that renders the LLM-drafted product-page snippet (FAQ Q&A or
 * description rewrite) for one product-related gap. The merchant copies
 * ``suggested_text`` into the storefront per ``placement_hint``; the
 * "Suggest more" zone re-fires the same endpoint with the merchant's
 * hint so the draft can be regenerated in place.
 *
 * @param {GapProductSuggestionModalProps} props - Component props.
 * @return {JSX.Element} Modal overlay.
 */
function GapProductSuggestionModal({
  gap,
  initial,
  onClose,
}: GapProductSuggestionModalProps): JSX.Element {
  const [language, setLanguage] = useState<string>(initial.language || 'en');
  const [productTitle, setProductTitle] = useState<string>(
    initial.product?.title || gap.target
  );
  const [productSku, setProductSku] = useState<string>(
    initial.product?.sku || ''
  );
  const [currentDescription, setCurrentDescription] = useState<string>(
    initial.product?.current_description || ''
  );
  const [customerQuery, setCustomerQuery] = useState<string>(
    initial.customer_query || ''
  );
  const [problem, setProblem] = useState<string>(initial.problem || '');
  const [suggestionType, setSuggestionType] = useState<'faq' | 'description'>(
    initial.suggestion_type || 'description'
  );
  const [suggestedText, setSuggestedText] = useState<string>(
    initial.suggested_text || ''
  );
  const [placementHint, setPlacementHint] = useState<string>(
    initial.placement_hint || ''
  );
  const [extraPrompt, setExtraPrompt] = useState<string>('');
  const [regenerating, setRegenerating] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const [copied, setCopied] = useState<boolean>(false);

  useEffect(() => {
    setLanguage(initial.language || 'en');
    setProductTitle(initial.product?.title || gap.target);
    setProductSku(initial.product?.sku || '');
    setCurrentDescription(initial.product?.current_description || '');
    setCustomerQuery(initial.customer_query || '');
    setProblem(initial.problem || '');
    setSuggestionType(initial.suggestion_type || 'description');
    setSuggestedText(initial.suggested_text || '');
    setPlacementHint(initial.placement_hint || '');
    setExtraPrompt('');
    setError(null);
    setCopied(false);
  }, [initial, gap.target]);

  useEffect(() => {
    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape' && !regenerating) onClose();
    };
    document.addEventListener('keydown', handleEscape);
    return () => {
      document.removeEventListener('keydown', handleEscape);
    };
  }, [onClose, regenerating]);

  const handleRegenerate = async (): Promise<void> => {
    if (regenerating) return;
    setError(null);
    setRegenerating(true);
    try {
      const trimmedHint: string = extraPrompt.trim();
      const firstSample = gap.samples[0];
      const result: IAgentGapProductSuggestionResponse | null =
        await prepareProductSuggestionForGap({
          target: gap.target,
          category: gap.category,
          sample_fingerprint: firstSample?.fingerprint ?? null,
          sample_message_index: firstSample?.message_index ?? null,
          extra_prompt: trimmedHint || null,
        });
      if (!result) {
        setError('Failed to regenerate the snippet.');
        return;
      }
      setLanguage(result.language || 'en');
      setProductTitle(result.product?.title || gap.target);
      setProductSku(result.product?.sku || '');
      setCurrentDescription(result.product?.current_description || '');
      setCustomerQuery(result.customer_query || '');
      setProblem(result.problem || '');
      setSuggestionType(result.suggestion_type || 'description');
      setSuggestedText(result.suggested_text || '');
      setPlacementHint(result.placement_hint || '');
      setExtraPrompt('');
      setCopied(false);
    } catch (regenerateError) {
      setError(
        regenerateError instanceof Error
          ? regenerateError.message
          : 'Failed to regenerate the snippet.'
      );
    } finally {
      setRegenerating(false);
    }
  };

  const handleCopy = async (): Promise<void> => {
    if (!suggestedText) return;
    try {
      await navigator.clipboard.writeText(suggestedText);
      setCopied(true);
      window.setTimeout(() => setCopied(false), 2000);
    } catch {
      setCopied(false);
    }
  };

  if (typeof document === 'undefined') return <></>;

  return createPortal(
    <div className="fixed inset-0 z-[9999] flex items-center justify-center">
      <div
        className="absolute inset-0 bg-black/50"
        onClick={() => !regenerating && onClose()}
      />
      <div className="relative z-10 mx-4 flex max-h-[90vh] w-[min(100%,56rem)] flex-col overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-2xl">
        <div className="flex items-start justify-between gap-3 border-b border-gray-200 px-6 py-4">
          <div className="space-y-1">
            <h2 className="text-base font-semibold text-gray-900">
              Product page suggestion
            </h2>
            <p className="text-xs text-gray-500">
              Paste this snippet into the product page so the agent has the
              answer next time a customer asks about{' '}
              <span className="font-semibold text-gray-900">{gap.target}</span>.
              Detected language: <span className="uppercase">{language}</span>.
            </p>
          </div>
          <button
            type="button"
            onClick={() => !regenerating && onClose()}
            aria-label="Close"
            className="flex h-7 w-7 cursor-pointer items-center justify-center rounded text-gray-500 hover:bg-gray-100 hover:text-gray-900"
          >
            ×
          </button>
        </div>

        <div className="flex-1 space-y-4 overflow-y-auto px-6 py-4">
          <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
            <div className="rounded-md border border-gray-200 bg-gray-50 p-3">
              <p className="text-[11px] font-semibold uppercase tracking-wide text-gray-500">
                Product
              </p>
              <p className="mt-1 text-sm font-medium text-gray-900">
                {productTitle || '—'}
              </p>
              {productSku && (
                <p className="text-xs text-gray-500">SKU: {productSku}</p>
              )}
            </div>
            <div className="rounded-md border border-gray-200 bg-gray-50 p-3">
              <p className="text-[11px] font-semibold uppercase tracking-wide text-gray-500">
                Customer asked
              </p>
              <p className="mt-1 text-sm text-gray-900">
                {customerQuery || '—'}
              </p>
            </div>
          </div>

          {problem && (
            <div className="rounded-md border border-amber-200 bg-amber-50 p-3">
              <p className="text-[11px] font-semibold uppercase tracking-wide text-amber-700">
                What was missing
              </p>
              <p className="mt-1 text-sm text-amber-900">{problem}</p>
            </div>
          )}

          {currentDescription && (
            <div className="space-y-1.5">
              <p className="text-xs font-medium text-gray-700">
                Current product description
              </p>
              <pre className="max-h-40 overflow-y-auto whitespace-pre-wrap rounded-md border border-gray-200 bg-gray-50 p-3 font-sans text-xs leading-relaxed text-gray-600">
                {currentDescription}
              </pre>
            </div>
          )}

          <div className="space-y-1.5">
            <div className="flex flex-wrap items-center gap-2">
              <p className="text-xs font-medium text-gray-700">
                Suggested snippet
              </p>
              <span
                className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${
                  suggestionType === 'faq'
                    ? 'border-sky-200 bg-sky-50 text-sky-700'
                    : 'border-pink-200 bg-pink-50 text-pink-700'
                }`}
              >
                {suggestionType === 'faq' ? (
                  <>
                    <FileText className="h-3 w-3" />
                    Add as FAQ entry
                  </>
                ) : (
                  <>
                    <PenLine className="h-3 w-3" />
                    Add to product description
                  </>
                )}
              </span>
              {placementHint && (
                <span className="text-[11px] text-gray-500">
                  · {placementHint}
                </span>
              )}
            </div>
            <textarea
              value={suggestedText}
              onChange={event => setSuggestedText(event.target.value)}
              disabled={regenerating}
              rows={10}
              placeholder="The AI draft will appear here. Edit before you copy if you want."
              className="block w-full rounded-md border border-gray-300 bg-white px-3 py-2 font-sans text-sm leading-relaxed text-gray-900 focus:border-[#B7007C] focus:outline-none focus:ring-1 focus:ring-[#B7007C]"
            />
            <div className="flex items-center justify-between gap-3">
              <p className="text-[11px] text-gray-500">
                Edit if needed, then click Copy.
              </p>
              <button
                type="button"
                onClick={handleCopy}
                disabled={!suggestedText || regenerating}
                className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-md bg-[#B7007C] px-3 text-xs font-semibold text-white shadow-sm shadow-[#B7007C]/30 transition-colors hover:bg-[#9c006a] disabled:cursor-not-allowed disabled:opacity-60"
              >
                {copied ? (
                  <>
                    <Check className="h-3.5 w-3.5" />
                    Copied
                  </>
                ) : (
                  <>
                    <Copy className="h-3.5 w-3.5" />
                    Copy
                  </>
                )}
              </button>
            </div>
          </div>

          <div className="space-y-1.5 rounded-md border border-dashed border-[#B7007C]/40 bg-[#fff5fa] p-3">
            <label
              htmlFor="gap-product-suggestion-extra-prompt"
              className="flex items-center gap-1.5 text-xs font-medium text-gray-700"
            >
              <Sparkles className="h-3.5 w-3.5 text-[#B7007C]" />
              Suggest more
            </label>
            <p className="text-xs text-gray-500">
              Tell the AI what to change in the snippet above (e.g. make it
              shorter, add the warranty period, more technical tone). Leave
              empty to regenerate from scratch.
            </p>
            <textarea
              id="gap-product-suggestion-extra-prompt"
              value={extraPrompt}
              onChange={event => setExtraPrompt(event.target.value)}
              maxLength={SUGGEST_MORE_MAX_LENGTH}
              disabled={regenerating}
              rows={3}
              placeholder="e.g. add the dimensions, mention free returns, more concise..."
              className="block w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm leading-relaxed text-gray-900 focus:border-[#B7007C] focus:outline-none focus:ring-1 focus:ring-[#B7007C]"
            />
            <div className="flex items-center justify-between gap-3">
              <p className="text-[11px] text-gray-500">
                {extraPrompt.length}/{SUGGEST_MORE_MAX_LENGTH}
              </p>
              <button
                type="button"
                onClick={handleRegenerate}
                disabled={regenerating}
                className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-md bg-[#B7007C] px-3 text-xs font-semibold text-white shadow-sm shadow-[#B7007C]/30 transition-colors hover:bg-[#9c006a] disabled:cursor-not-allowed disabled:opacity-60"
              >
                {regenerating ? (
                  <>
                    <span className="h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/30 border-t-white" />
                    Regenerating...
                  </>
                ) : (
                  <>
                    <Sparkles className="h-3.5 w-3.5" />
                    Regenerate
                  </>
                )}
              </button>
            </div>
          </div>

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

        <div className="flex items-center justify-end gap-3 border-t border-gray-200 bg-gray-50 px-6 py-3">
          <button
            type="button"
            onClick={() => !regenerating && onClose()}
            disabled={regenerating}
            className="inline-flex h-9 cursor-pointer items-center rounded-md border border-gray-200 bg-white px-4 text-sm font-medium text-gray-700 transition-colors hover:border-gray-300 disabled:cursor-not-allowed disabled:opacity-50"
          >
            Done
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
}

export default GapProductSuggestionModal;
