// CMS content editor — title / category / type / subject / body /
// published toggle. For quizzes, also embeds QuestionsEditor.
//
// New content: passes `null` id and POSTs on save. Existing content:
// passes id and PUTs. Both refresh the content list query.
//
// Body is a plain textarea — no rich editor in this first React port.
// (Vanilla used a Quill-ish toolbar; that lands as a follow-up if
// users actually start using it.)

import { useEffect, useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api, ApiError } from '@/lib/api';
import RichTextEditor from '@/components/RichTextEditor';
import type { CmsCategory, CmsContentDetail, CmsQuestion, ContentType } from './cms-types';
import QuestionsEditor from './QuestionsEditor';
import SlideEditor from './SlideEditor';
import AiGenerator, { type GeneratedPayload } from './AiGenerator';

interface CategoriesOk { success: true; categories: CmsCategory[] }
interface ContentDetailOk { success: true; content: CmsContentDetail }

interface Props {
  id: number | null;        // null = creating new
  initialType: ContentType; // for creates — pre-selects the type
  onClose: () => void;
}

const input = 'rounded-md border border-input bg-background px-3 py-2 text-sm';
const btn = 'inline-flex items-center gap-1 rounded-md border border-border bg-background px-3 py-1.5 text-xs font-medium hover:bg-muted disabled:opacity-50';
const btnPrimary = 'inline-flex items-center gap-1 rounded-md bg-primary text-primary-foreground px-3 py-1.5 text-xs font-medium disabled:opacity-50';

export default function ContentEditor({ id, initialType, onClose }: Props) {
  const qc = useQueryClient();
  const isNew = id == null;
  const [title, setTitle] = useState('');
  const [subject, setSubject] = useState('');
  const [body, setBody] = useState('');
  const [categoryId, setCategoryId] = useState<number | ''>('');
  const [contentType, setContentType] = useState<ContentType>(initialType);
  const [published, setPublished] = useState(false);
  const [questions, setQuestions] = useState<CmsQuestion[]>([]);
  const [msg, setMsg] = useState<{ kind: 'ok' | 'err'; text: string } | null>(null);
  const [aiOpen, setAiOpen] = useState(false);

  function applyAi(payload: GeneratedPayload, ctype: ContentType) {
    setContentType(ctype);
    // Presentation → body is the Marp markdown (becomes the slide-editor
    // source after split by \n---\n).
    if (ctype === 'presentation' && payload.marpMarkdown) {
      setBody(payload.marpMarkdown);
      // Extract title from first # heading so the editor can save immediately.
      const titleMatch = payload.marpMarkdown.match(/^#\s+(.+)$/m);
      if (titleMatch) setTitle(titleMatch[1]);
    } else {
      if (payload.title) setTitle(payload.title);
      if (payload.subject !== undefined) setSubject(payload.subject);
      if (payload.body !== undefined) setBody(payload.body);
    }
    if (payload.questions && payload.questions.length) {
      setQuestions(payload.questions);
    }
    setAiOpen(false);
    setMsg({ kind: 'ok', text: 'Content generated — review, then save.' });
  }

  const cats = useQuery<CategoriesOk>({
    queryKey: ['cms-categories'],
    queryFn: () => api.get<CategoriesOk>('/api/learning-admin/categories'),
  });

  const detail = useQuery<ContentDetailOk>({
    queryKey: ['cms-content-detail', id],
    queryFn: () => api.get<ContentDetailOk>('/api/learning-admin/content/' + id),
    enabled: !isNew,
  });

  // Hydrate state from server when editing an existing item.
  useEffect(() => {
    if (!detail.data?.content) return;
    const c = detail.data.content;
    setTitle(c.title);
    setSubject(c.subject || '');
    setBody(c.body || '');
    setCategoryId(c.category_id ?? '');
    setContentType(c.content_type);
    setPublished(!!c.published);
    setQuestions(c.questions || []);
  }, [detail.data]);

  const save = useMutation<{ success: true; id: number }, Error, void>({
    mutationFn: async () => {
      const body_ = {
        title, subject, body,
        category_id: categoryId === '' ? null : categoryId,
        content_type: contentType,
        published,
      };
      if (isNew) {
        return api.post<{ success: true; id: number }>('/api/learning-admin/content', body_);
      }
      await api.put<{ success: true }>('/api/learning-admin/content/' + id, body_);
      return { success: true as const, id: id! };
    },
    onSuccess: (d) => {
      qc.invalidateQueries({ queryKey: ['cms-content'] });
      qc.invalidateQueries({ queryKey: ['cms-stats'] });
      qc.invalidateQueries({ queryKey: ['cms-content-detail', d.id] });
      setMsg({ kind: 'ok', text: isNew ? 'Created — switch to the list to add questions' : 'Saved' });
    },
    onError: (e) => setMsg({ kind: 'err', text: (e as ApiError).message || 'Save failed' }),
  });

  return (
    <div className="flex-1 space-y-3 min-w-0" data-testid="cms-editor">
      <div className="flex items-center justify-between">
        <h3 className="text-base font-semibold">
          {isNew ? 'New ' + contentType : 'Edit ' + contentType}
        </h3>
        <div className="flex gap-2">
          <button type="button" onClick={() => setAiOpen((v) => !v)} className={btnPrimary} data-testid="cms-open-ai">
            ✨ {aiOpen ? 'Hide AI' : 'Generate with AI'}
          </button>
          <button type="button" onClick={onClose} className={btn}>← Back to list</button>
        </div>
      </div>

      {aiOpen && (
        <AiGenerator
          contentType={contentType}
          onChangeType={setContentType}
          onGenerated={applyAi}
          onCancel={() => setAiOpen(false)}
        />
      )}

      <div className="rounded-lg border border-border bg-card p-4 space-y-3">
        <label className="block">
          <span className="block text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1">Title</span>
          <input
            type="text"
            className={input + ' w-full'}
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            data-testid="cms-edit-title"
          />
        </label>

        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
          <label className="block">
            <span className="block text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1">Type</span>
            <select
              className={input + ' w-full'}
              value={contentType}
              onChange={(e) => setContentType(e.target.value as ContentType)}
              data-testid="cms-edit-type"
            >
              <option value="article">Article</option>
              <option value="pearl">Pearl</option>
              <option value="quiz">Quiz</option>
              <option value="presentation">Presentation</option>
            </select>
          </label>
          <label className="block">
            <span className="block text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1">Category</span>
            <select
              className={input + ' w-full'}
              value={categoryId}
              onChange={(e) => setCategoryId(e.target.value === '' ? '' : Number(e.target.value))}
              data-testid="cms-edit-category"
            >
              <option value="">Uncategorized</option>
              {(cats.data?.categories || []).map((c) => (
                <option key={c.id} value={c.id}>{c.name}</option>
              ))}
            </select>
          </label>
          <label className="flex items-end gap-2">
            <input
              type="checkbox"
              checked={published}
              onChange={(e) => setPublished(e.target.checked)}
              className="h-4 w-4"
              data-testid="cms-edit-published"
            />
            <span className="text-sm">Published</span>
          </label>
        </div>

        <label className="block">
          <span className="block text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1">Subject (optional)</span>
          <input
            type="text"
            className={input + ' w-full'}
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            placeholder="e.g. Asthma, Bronchiolitis"
          />
        </label>

        <div>
          <span className="block text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1">
            Body
          </span>
          {contentType === 'presentation' ? (
            <SlideEditor value={body} onChange={setBody} />
          ) : (
            <RichTextEditor
              value={body}
              onChange={setBody}
              variant="default"
              minHeight="min-h-[320px]"
              placeholder="Write the content body…"
              testId="cms-edit-body"
            />
          )}
        </div>

        <div className="flex items-center gap-2">
          <button
            type="button"
            onClick={() => save.mutate()}
            disabled={save.isPending || !title.trim()}
            className={btnPrimary}
            data-testid="cms-save"
          >
            {save.isPending ? 'Saving…' : (isNew ? 'Create' : 'Save changes')}
          </button>
          {msg && (
            <span className={'text-xs ' + (msg.kind === 'ok' ? 'text-green-600' : 'text-destructive')}>
              {msg.text}
            </span>
          )}
        </div>
      </div>

      {!isNew && contentType === 'quiz' && (
        <div className="rounded-lg border border-border bg-card p-4">
          <QuestionsEditor
            contentId={id!}
            questions={questions}
            onChange={setQuestions}
          />
        </div>
      )}
    </div>
  );
}
