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

import type {
  PageContentType,
  PageTemplate,
} from '../../service/visibility/visibility.interface';
import { generateArticle } from '../../service/visibility/visibility.service';

import {
  contentTypeLabel,
  contentTypeTone,
  languageLabel,
  PAGE_CONTENT_TYPES,
  toneToBadgeClass,
} from './helpers';
import LanguageMultiSelect from './LanguageMultiSelect';
import Modal from './Modal';

/** Most additional languages a merchant may add on top of the primary one. */
const MAX_ADDITIONAL_LANGUAGES = 2;
/** Matches the backend ``instructions`` cap on the generate request. */
const MAX_INSTRUCTIONS_CHARS = 4000;

/** Props for {@link RunPageTemplateModal}. */
interface RunPageTemplateModalProps {
  open: boolean;
  onClose: () => void;
  clientId: string;
  token: string;
  brandId: string;
  /** Brand language; the article's primary language unless extras are added. */
  language: string;
  /**
   * The brief to run. When set, the modal pre-fills from it (page type +
   * directive + target prompts) and the type is locked to the brief. When
   * ``null`` the merchant picks the page type for a one-off run.
   */
  template: PageTemplate | null;
  /** Fired after an article is dispatched so the parent can route / refresh. */
  onStarted: () => void;
}

/**
 * "Run template" modal. Pre-fills the topic, page type and directive from a
 * saved page-content brief, lets the merchant edit the directive (and topic)
 * for this run, optionally add languages, then dispatches article generation.
 * The edited directive overrides the brief's saved one for this run only.
 *
 * @param {RunPageTemplateModalProps} props - Modal props.
 * @returns {JSX.Element} The modal.
 */
const RunPageTemplateModal = ({
  open,
  onClose,
  clientId,
  token,
  brandId,
  language,
  template,
  onStarted,
}: RunPageTemplateModalProps): JSX.Element | null => {
  const primary = (language || 'en').toLowerCase();
  const [topic, setTopic] = useState('');
  const [contentType, setContentType] = useState<PageContentType>('blog');
  const [instructions, setInstructions] = useState('');
  const [additional, setAdditional] = useState<string[]>([]);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Re-seed every time the modal opens so a previous run never leaks into the
  // next. The template's saved directive pre-fills the (editable) textarea.
  // Profile runs pre-fill the topic from the template name: the directive
  // already defines the whole output, so the merchant shouldn't have to
  // invent a topic for "X Bio" or "Press Boilerplate".
  useEffect(() => {
    if (!open) return;
    setTopic(template?.content_type === 'profile' ? template.name : '');
    setContentType(template?.content_type ?? 'blog');
    setInstructions(template?.default_instructions ?? '');
    setAdditional([]);
    setError(null);
    setBusy(false);
  }, [open, template]);

  const handleGenerate = async (): Promise<void> => {
    if (topic.trim().length < 5) {
      setError('Give the page a clear topic (at least a few words).');

      return;
    }
    setBusy(true);
    setError(null);
    const languages = additional.length ? [primary, ...additional] : undefined;
    try {
      await generateArticle(clientId, token, {
        brand_id: brandId,
        topic: topic.trim(),
        content_type: contentType,
        // Empty for a preset run - the backend then generates from content_type
        // + instructions without a saved template.
        template_id: template?.template_id || undefined,
        instructions: instructions.trim() || undefined,
        target_prompts: template?.default_target_prompts,
        keywords: template?.default_keywords,
        languages,
        triggered_by: 'manual',
      });
      onClose();
      onStarted();
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : 'Could not start generation. Try again.'
      );
    } finally {
      setBusy(false);
    }
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={template ? `Run "${template.name}"` : 'Generate a page'}
      footer={
        <>
          <button
            type="button"
            onClick={onClose}
            disabled={busy}
            className="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={handleGenerate}
            disabled={busy}
            className="rounded-md bg-pink-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-pink-700 disabled:opacity-60"
          >
            {busy
              ? 'Starting...'
              : additional.length
                ? `Generate in ${additional.length + 1} languages`
                : 'Generate'}
          </button>
        </>
      }
    >
      <div className="flex flex-col gap-4">
        <p className="text-sm text-gray-500">
          Set the topic and tweak the directive for this run. Your edits here
          override the saved template for this generation only.
        </p>

        {error && (
          <div className="rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700">
            {error}
          </div>
        )}

        <label className="flex flex-col gap-1.5 text-sm">
          <span className="font-medium text-gray-700">Topic</span>
          <input
            type="text"
            value={topic}
            onChange={event => setTopic(event.target.value)}
            placeholder="What should this page be about?"
            disabled={busy}
            autoFocus
            className="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 focus:border-pink-500 focus:outline-none focus:ring-1 focus:ring-pink-500"
          />
        </label>

        <div className="flex flex-col gap-1.5">
          <span className="text-sm font-medium text-gray-700">Page type</span>
          {template ? (
            <div>
              <span
                className={`rounded-full px-2 py-0.5 text-xs font-medium ${toneToBadgeClass(
                  contentTypeTone(contentType)
                )}`}
              >
                {contentTypeLabel(contentType)}
              </span>
            </div>
          ) : (
            <div className="flex flex-wrap gap-2">
              {PAGE_CONTENT_TYPES.map(type => (
                <button
                  key={type}
                  type="button"
                  disabled={busy}
                  onClick={() => setContentType(type)}
                  className={`rounded-full border px-3 py-1 text-xs font-medium transition-colors ${
                    contentType === type
                      ? 'border-pink-600 bg-pink-50 text-pink-700'
                      : 'border-gray-300 bg-white text-gray-500 hover:text-gray-700'
                  }`}
                >
                  {contentTypeLabel(type)}
                </button>
              ))}
            </div>
          )}
        </div>

        <label className="flex flex-col gap-1.5 text-sm">
          <span className="font-medium text-gray-700">Instructions</span>
          <textarea
            value={instructions}
            onChange={event =>
              setInstructions(
                event.target.value.slice(0, MAX_INSTRUCTIONS_CHARS)
              )
            }
            placeholder="Structure, tone, what to include or avoid…"
            rows={5}
            disabled={busy}
            className="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 focus:border-pink-500 focus:outline-none focus:ring-1 focus:ring-pink-500"
          />
        </label>

        <div className="flex flex-col gap-1.5">
          <span className="text-sm font-medium text-gray-700">
            Languages
            <span className="ml-1 font-normal text-gray-500">
              (primary {languageLabel(primary)})
            </span>
          </span>
          <LanguageMultiSelect
            value={additional}
            onChange={setAdditional}
            max={MAX_ADDITIONAL_LANGUAGES}
            exclude={[primary]}
            disabled={busy}
          />
        </div>
      </div>
    </Modal>
  );
};

export default RunPageTemplateModal;
