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

import type { PromptResponse } from '../../service/visibility/visibility.interface';
import {
  regeneratePrompt,
  updatePrompt,
} from '../../service/visibility/visibility.service';

import Modal from './Modal';

/** One-click rewrite presets; the backend grounds the actual product wording. */
const REGENERATE_PRESETS: { label: string; instruction: string }[] = [
  {
    label: 'More specific',
    instruction:
      'Make it more specific and long-tail, naming a concrete product and use-case.',
  },
  {
    label: 'Where to buy',
    instruction: 'Phrase it as a where-to-buy / purchase-intent query.',
  },
  {
    label: 'Comparison',
    instruction:
      'Turn it into a comparison of two real options within the same product type.',
  },
  {
    label: 'Shorter',
    instruction:
      'Make it shorter and more natural, the way a person quickly types it.',
  },
];

/** Props for {@link EditPromptModal}. */
interface EditPromptModalProps {
  /** Modal open flag. */
  open: boolean;
  /** The prompt being edited. ``null`` hides the modal body. */
  prompt: PromptResponse | null;
  /** Close handler. Fires on cancel and after a successful save. */
  onClose: () => void;
  /** Called with the refreshed prompt row after the backend confirms. */
  onSaved: (updated: PromptResponse) => void;
  /** Recomaze client id. */
  clientId: string;
  /** Recomaze JWT. */
  token: string;
  /** Brand the prompt belongs to. */
  brandId: string;
}

/**
 * Free-text edit dialog for one tracked prompt. The change takes effect
 * on the next weekly scan, so we surface that expectation explicitly.
 *
 * @param {EditPromptModalProps} props - Dialog props.
 * @returns {JSX.Element} The modal.
 */
const EditPromptModal = ({
  open,
  prompt,
  onClose,
  onSaved,
  clientId,
  token,
  brandId,
}: EditPromptModalProps): JSX.Element => {
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [instruction, setInstruction] = useState('');
  const [regenerating, setRegenerating] = useState(false);

  useEffect(() => {
    if (open && prompt) {
      setText(prompt.prompt_text);
      setError(null);
      setInstruction('');
    }
  }, [open, prompt]);

  const handleRegenerate = async (
    presetInstruction?: string
  ): Promise<void> => {
    if (!prompt) return;
    const steer = (presetInstruction ?? instruction).trim();
    setRegenerating(true);
    setError(null);
    try {
      const updated = await regeneratePrompt(
        clientId,
        token,
        brandId,
        prompt.prompt_id,
        { instruction: steer || undefined }
      );
      setText(updated.prompt_text);
      onSaved(updated);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : 'Failed to regenerate prompt.'
      );
    } finally {
      setRegenerating(false);
    }
  };

  const trimmed = text.trim();
  const unchanged = prompt !== null && trimmed === prompt.prompt_text.trim();
  const tooShort = trimmed.length < 3;

  const handleSave = async (): Promise<void> => {
    if (!prompt || tooShort || unchanged) return;
    setSubmitting(true);
    setError(null);
    try {
      const updated = await updatePrompt(
        clientId,
        token,
        brandId,
        prompt.prompt_id,
        { text: trimmed }
      );
      onSaved(updated);
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save prompt.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title="Edit tracked prompt"
      footer={
        <>
          <button
            type="button"
            onClick={onClose}
            disabled={submitting || regenerating}
            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={handleSave}
            disabled={
              !prompt || tooShort || unchanged || submitting || regenerating
            }
            className="rounded-md bg-pink-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-pink-700 disabled:opacity-60"
          >
            {submitting ? 'Saving...' : 'Save'}
          </button>
        </>
      }
    >
      <div className="flex flex-col gap-3">
        {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">Prompt text</span>
          <textarea
            value={text}
            onChange={event => setText(event.target.value)}
            rows={4}
            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"
            autoFocus
          />
          <span className="text-xs text-gray-500">
            Edits take effect on the next weekly scan. Category and tracking
            status stay the same.
          </span>
        </label>

        <div className="flex flex-col gap-2 rounded-lg border border-gray-200 p-3">
          <span className="text-sm font-medium text-gray-700">
            Regenerate with AI
          </span>
          <div className="flex flex-wrap gap-1.5">
            {REGENERATE_PRESETS.map(preset => (
              <button
                key={preset.label}
                type="button"
                disabled={regenerating || submitting}
                onClick={() => handleRegenerate(preset.instruction)}
                className="rounded-full border border-gray-300 px-2.5 py-1 text-xs text-gray-600 hover:bg-gray-50 disabled:opacity-50"
              >
                {preset.label}
              </button>
            ))}
          </div>
          <textarea
            value={instruction}
            onChange={event => setInstruction(event.target.value)}
            rows={2}
            placeholder="Or tell the AI how to change it (optional), then Regenerate."
            disabled={regenerating || submitting}
            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"
          />
          <div>
            <button
              type="button"
              disabled={regenerating || submitting}
              onClick={() => handleRegenerate()}
              className="rounded-md bg-pink-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-pink-700 disabled:opacity-60"
            >
              {regenerating ? 'Regenerating...' : 'Regenerate with AI'}
            </button>
          </div>
        </div>
      </div>
    </Modal>
  );
};

export default EditPromptModal;
