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

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

import { contentTypeLabel, PAGE_CONTENT_TYPES } from './helpers';
import Modal from './Modal';

/** Matches the backend ``default_instructions`` cap. */
const MAX_INSTRUCTIONS_CHARS = 4000;

/** Props for {@link PageTemplateEditorModal}. */
interface PageTemplateEditorModalProps {
  open: boolean;
  onClose: () => void;
  clientId: string;
  token: string;
  brandId: string;
  /** Brand language, stamped on new templates. */
  language: string;
  /** The template being edited, or ``null`` to create a new one. */
  template: PageTemplate | null;
  /** Fired with the saved row so the parent can merge it into the gallery. */
  onSaved: (saved: PageTemplate) => void;
}

/** Split a textarea's "one per line" value into a trimmed, non-empty list. */
const linesToList = (value: string): string[] =>
  value
    .split('\n')
    .map(line => line.trim())
    .filter(line => line.length > 0);

/**
 * Create / edit modal for a saved page-content brief. Backs both the "+ Create
 * new" entry and each card's "Edit" action. Calls the visibility service
 * directly (client-side), mirroring the generate modals.
 *
 * @param {PageTemplateEditorModalProps} props - Modal props.
 * @returns {JSX.Element} The modal.
 */
const PageTemplateEditorModal = ({
  open,
  onClose,
  clientId,
  token,
  brandId,
  language,
  template,
  onSaved,
}: PageTemplateEditorModalProps): JSX.Element | null => {
  const [name, setName] = useState('');
  const [contentType, setContentType] = useState<PageContentType>('blog');
  const [description, setDescription] = useState('');
  const [instructions, setInstructions] = useState('');
  const [targetPrompts, setTargetPrompts] = useState('');
  const [keywords, setKeywords] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // A saved template carries a non-empty id; a preset fork (id "") or a fresh
  // template does not, so it saves as a new merchant-owned row.
  const isEdit = Boolean(template?.template_id);

  // Re-seed from the edited row (or blank for create) each time the modal opens.
  useEffect(() => {
    if (!open) return;
    setName(template?.name ?? '');
    setContentType(template?.content_type ?? 'blog');
    setDescription(template?.description ?? '');
    setInstructions(template?.default_instructions ?? '');
    setTargetPrompts((template?.default_target_prompts ?? []).join('\n'));
    setKeywords((template?.default_keywords ?? []).join('\n'));
    setError(null);
    setBusy(false);
  }, [open, template]);

  const handleSave = async (): Promise<void> => {
    if (name.trim().length === 0) {
      setError('Give the template a name.');

      return;
    }
    setBusy(true);
    setError(null);
    const body = {
      content_type: contentType,
      name: name.trim(),
      description: description.trim(),
      default_instructions: instructions.trim(),
      default_target_prompts: linesToList(targetPrompts),
      default_keywords: linesToList(keywords),
    };
    try {
      // Only a saved template (non-empty id) is patched; a preset fork or a
      // fresh template creates a new merchant-owned row.
      const saved = isEdit
        ? await updatePageTemplate(
            clientId,
            token,
            brandId,
            template!.template_id,
            body
          )
        : await createPageTemplate(clientId, token, brandId, {
            ...body,
            language,
          });
      onClose();
      onSaved(saved);
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : 'Could not save the template. Try again.'
      );
    } finally {
      setBusy(false);
    }
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={isEdit ? 'Edit template' : 'New page template'}
      size="lg"
      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={handleSave}
            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 ? 'Saving...' : isEdit ? 'Save changes' : 'Create template'}
          </button>
        </>
      }
    >
      <div className="flex flex-col gap-4">
        <p className="text-sm text-gray-500">
          Save a reusable brief: a page type plus a default directive you can
          replay from the gallery, tweaking it per run.
        </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">Name</span>
          <input
            type="text"
            value={name}
            onChange={event => setName(event.target.value)}
            placeholder="e.g. Service page"
            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">Page type</span>
          <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">Description</span>
          <textarea
            value={description}
            onChange={event => setDescription(event.target.value)}
            placeholder="Short note shown on the card (optional)"
            rows={2}
            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>

        <label className="flex flex-col gap-1.5 text-sm">
          <span className="font-medium text-gray-700">
            Default instructions
          </span>
          <textarea
            value={instructions}
            onChange={event =>
              setInstructions(
                event.target.value.slice(0, MAX_INSTRUCTIONS_CHARS)
              )
            }
            placeholder="Structure, tone, what every run should include or avoid…"
            rows={6}
            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="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <label className="flex flex-col gap-1.5 text-sm">
            <span className="font-medium text-gray-700">Target prompts</span>
            <textarea
              value={targetPrompts}
              onChange={event => setTargetPrompts(event.target.value)}
              placeholder="One per line"
              rows={4}
              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>
          <label className="flex flex-col gap-1.5 text-sm">
            <span className="font-medium text-gray-700">Keywords</span>
            <textarea
              value={keywords}
              onChange={event => setKeywords(event.target.value)}
              placeholder="One per line"
              rows={4}
              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>
      </div>
    </Modal>
  );
};

export default PageTemplateEditorModal;
