import { useEffect, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import {
  ArrowLeft, Save, Plus, Trash2, GripVertical, History, RotateCcw,
  Sparkles, Send, CheckCircle2, Globe, XCircle, Archive, CalendarClock, Type, Image as ImageIcon, Package, Megaphone,
} from 'lucide-react'
import StatusBadge from '../components/StatusBadge'
import { PageHeader, Btn, Field, Modal, Card, safeJson } from '../components/ui'
import { canWrite, canPublish } from '../components/rbac'
import {
  getContent, createContent, updateContent, getContentVersions,
  transitionContent, rollbackContent, aiDraft, aiSeo,
} from '../api/client'

type Block = { type: string; [k: string]: any }

const BLOCK_TYPES = [
  { type: 'text', label: '텍스트', icon: Type },
  { type: 'image', label: '이미지', icon: ImageIcon },
  { type: 'product', label: '상품', icon: Package },
  { type: 'banner', label: '배너', icon: Megaphone },
]

function newBlock(type: string): Block {
  switch (type) {
    case 'image': return { type, url: '', alt: '' }
    case 'product': return { type, productId: '', label: '' }
    case 'banner': return { type, bannerId: '', label: '' }
    default: return { type: 'text', text: '' }
  }
}

const empty = {
  contentType: 'PAGE', slug: '', title: '', summary: '', blocks: [] as Block[],
  locale: 'ko', tags: '', seoMeta: { title: '', description: '', keywords: '' }, menuId: null as number | null,
}

export default function ContentEditor() {
  const { id } = useParams()
  const nav = useNavigate()
  const isNew = !id || id === 'new'
  const [form, setForm] = useState<any>({ ...empty })
  const [status, setStatus] = useState('DRAFT')
  const [version, setVersion] = useState(1)
  const [scheduledAt, setScheduledAt] = useState<string | null>(null)
  const [versions, setVersions] = useState<any[]>([])
  const [showVersions, setShowVersions] = useState(false)
  const [showSchedule, setShowSchedule] = useState(false)
  const [schedAt, setSchedAt] = useState('')
  const [aiBusy, setAiBusy] = useState('')
  const [msg, setMsg] = useState('')
  const writable = canWrite()
  const publishable = canPublish()

  useEffect(() => {
    if (isNew) return
    getContent(Number(id)).then(c => {
      if (!c) return
      setForm({
        contentType: c.contentType, slug: c.slug, title: c.title, summary: c.summary || '',
        blocks: safeJson(c.blocks, []), locale: c.locale, tags: c.tags || '',
        seoMeta: safeJson(c.seoMeta, { title: '', description: '', keywords: '' }), menuId: c.menuId ?? null,
      })
      setStatus(c.status); setVersion(c.version); setScheduledAt(c.scheduledAt)
    }).catch(() => {})
  }, [id])

  const loadVersions = () => {
    getContentVersions(Number(id)).then(v => { setVersions(v || []); setShowVersions(true) }).catch(() => setVersions([]))
  }

  const setBlock = (i: number, patch: object) => {
    const b = [...form.blocks]; b[i] = { ...b[i], ...patch }; setForm({ ...form, blocks: b })
  }
  const addBlock = (type: string) => setForm({ ...form, blocks: [...form.blocks, newBlock(type)] })
  const removeBlock = (i: number) => setForm({ ...form, blocks: form.blocks.filter((_: any, j: number) => j !== i) })
  const moveBlock = (i: number, dir: -1 | 1) => {
    const j = i + dir
    if (j < 0 || j >= form.blocks.length) return
    const b = [...form.blocks];[b[i], b[j]] = [b[j], b[i]]; setForm({ ...form, blocks: b })
  }

  const save = async () => {
    setMsg('')
    const payload = { ...form }
    try {
      if (isNew) {
        const c = await createContent(payload)
        nav(`/contents/${c.id}`, { replace: true })
      } else {
        const c = await updateContent(Number(id), payload)
        setVersion(c.version); setMsg('저장되었습니다.')
      }
    } catch (e: any) {
      setMsg(e?.response?.data?.message || '저장에 실패했습니다.')
    }
  }

  const transition = async (action: string) => {
    if (isNew) { setMsg('먼저 저장하세요.'); return }
    try {
      const c = await transitionContent(Number(id), { action })
      setStatus(c.status); setScheduledAt(c.scheduledAt)
      setMsg(`상태 전환: ${c.status}`)
    } catch (e: any) {
      setMsg(e?.response?.data?.message || '상태 전환에 실패했습니다 (권한 확인).')
    }
  }

  const doSchedule = async () => {
    if (!schedAt) return
    try {
      const c = await transitionContent(Number(id), { action: 'schedule', scheduledAt: new Date(schedAt).toISOString() })
      setStatus(c.status); setScheduledAt(c.scheduledAt); setShowSchedule(false); setMsg('예약 게시가 설정되었습니다.')
    } catch (e: any) { setMsg(e?.response?.data?.message || '예약에 실패했습니다.') }
  }

  const doRollback = async (v: number) => {
    if (!window.confirm(`v${v} 로 롤백하시겠습니까? (DRAFT 로 복원)`)) return
    try {
      const c = await rollbackContent(Number(id), v)
      setForm({
        contentType: c.contentType, slug: c.slug, title: c.title, summary: c.summary || '',
        blocks: safeJson(c.blocks, []), locale: c.locale, tags: c.tags || '',
        seoMeta: safeJson(c.seoMeta, {}), menuId: c.menuId ?? null,
      })
      setStatus(c.status); setVersion(c.version); setShowVersions(false); setMsg(`v${v} 로 롤백되었습니다.`)
    } catch (e: any) { setMsg(e?.response?.data?.message || '롤백에 실패했습니다.') }
  }

  const genDraft = async () => {
    setAiBusy('draft')
    try {
      const r = await aiDraft(form.contentType?.toLowerCase() || 'page', form.title || form.slug || '콘텐츠', 'professional')
      if (r?.draft) addBlockWithText(r.draft)
    } catch { setMsg('AI 초안 생성 실패 (Ollama 폴백)') } finally { setAiBusy('') }
  }
  const addBlockWithText = (text: string) =>
    setForm((f: any) => ({ ...f, blocks: [...f.blocks, { type: 'text', text }] }))

  const genSeo = async () => {
    setAiBusy('seo')
    const body = form.blocks.filter((b: Block) => b.type === 'text').map((b: Block) => b.text).join('\n')
    try {
      const r = await aiSeo(form.title || '', body)
      setForm((f: any) => ({ ...f, seoMeta: { ...f.seoMeta, description: r?.metaDescription || f.seoMeta.description, keywords: (r?.keywords || []).join(', ') } }))
      setMsg(`AI SEO 제안 적용 (점수 ${r?.score ?? '-'})`)
    } catch { setMsg('AI SEO 제안 실패') } finally { setAiBusy('') }
  }

  return (
    <div>
      <PageHeader
        title={isNew ? '새 콘텐츠' : '콘텐츠 편집'}
        subtitle={isNew ? '헤드리스 블록 콘텐츠 작성' : `v${version}`}
        actions={
          <div className="flex items-center gap-2">
            <Btn variant="ghost" onClick={() => nav('/contents')}><ArrowLeft size={15} /> 목록</Btn>
            {!isNew && <StatusBadge status={scheduledAt && status !== 'PUBLISHED' ? 'SCHEDULED' : status} />}
            {!isNew && <Btn variant="ghost" onClick={loadVersions}><History size={15} /> 버전</Btn>}
            {writable && <Btn onClick={save}><Save size={15} /> 저장</Btn>}
          </div>
        }
      />

      {msg && <div className="mb-4 text-sm rounded-lg px-4 py-2.5 bg-brand/10 border border-brand/30 text-brand">{msg}</div>}

      {/* 워크플로우 액션 바 */}
      {!isNew && (
        <div className="flex flex-wrap items-center gap-2 mb-5 bg-card border border-edge rounded-xl p-3">
          <span className="text-xs text-slate-500 mr-1">워크플로우:</span>
          <Btn size="sm" variant="ghost" onClick={() => transition('submit')}><Send size={13} /> 검토 요청</Btn>
          <Btn size="sm" variant="ghost" disabled={!publishable} onClick={() => transition('approve')} title={publishable ? '' : 'Editor+ 필요'}><CheckCircle2 size={13} /> 승인</Btn>
          <Btn size="sm" variant="ghost" disabled={!publishable} onClick={() => transition('publish')} title={publishable ? '' : 'Editor+ 필요'}><Globe size={13} /> 발행</Btn>
          <Btn size="sm" variant="ghost" disabled={!publishable} onClick={() => transition('reject')} title={publishable ? '' : 'Editor+ 필요'}><XCircle size={13} /> 반려</Btn>
          <Btn size="sm" variant="ghost" disabled={!publishable} onClick={() => transition('archive')} title={publishable ? '' : 'Editor+ 필요'}><Archive size={13} /> 보관</Btn>
          <Btn size="sm" variant="ghost" disabled={!publishable} onClick={() => { setSchedAt(''); setShowSchedule(true) }} title={publishable ? '' : 'Editor+ 필요'}><CalendarClock size={13} /> 예약 게시</Btn>
          {scheduledAt && <span className="text-[11px] text-violet-400 ml-1">예약: {new Date(scheduledAt).toLocaleString('ko-KR')}</span>}
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
        {/* 메타 */}
        <Card title="기본 정보" className="lg:col-span-1 self-start">
          <div className="space-y-3">
            <Field label="제목"><input className="inp" value={form.title} onChange={e => setForm({ ...form, title: e.target.value })} /></Field>
            <Field label="슬러그"><input className="inp" value={form.slug} onChange={e => setForm({ ...form, slug: e.target.value })} placeholder="url-slug" /></Field>
            <div className="grid grid-cols-2 gap-3">
              <Field label="유형">
                <select className="inp" value={form.contentType} onChange={e => setForm({ ...form, contentType: e.target.value })}>
                  {['PAGE', 'POST', 'PRODUCT', 'LANDING'].map(t => <option key={t}>{t}</option>)}
                </select>
              </Field>
              <Field label="로케일">
                <select className="inp" value={form.locale} onChange={e => setForm({ ...form, locale: e.target.value })}>
                  {['ko', 'en', 'ja', 'zh'].map(t => <option key={t}>{t}</option>)}
                </select>
              </Field>
            </div>
            <Field label="요약"><textarea className="inp" value={form.summary} onChange={e => setForm({ ...form, summary: e.target.value })} /></Field>
            <Field label="태그 (쉼표 구분)"><input className="inp" value={form.tags} onChange={e => setForm({ ...form, tags: e.target.value })} /></Field>
          </div>

          <div className="mt-5 pt-4 border-t border-edge">
            <div className="flex items-center justify-between mb-2">
              <span className="text-xs font-semibold text-slate-300 flex items-center gap-1"><Sparkles size={13} className="text-accent" /> SEO 메타</span>
              <Btn size="sm" variant="ghost" disabled={!!aiBusy} onClick={genSeo}><Sparkles size={12} /> {aiBusy === 'seo' ? '생성 중…' : 'AI 제안'}</Btn>
            </div>
            <div className="space-y-2">
              <input className="inp" placeholder="SEO 제목" value={form.seoMeta?.title || ''} onChange={e => setForm({ ...form, seoMeta: { ...form.seoMeta, title: e.target.value } })} />
              <textarea className="inp" placeholder="메타 설명" value={form.seoMeta?.description || ''} onChange={e => setForm({ ...form, seoMeta: { ...form.seoMeta, description: e.target.value } })} />
              <input className="inp" placeholder="키워드" value={form.seoMeta?.keywords || ''} onChange={e => setForm({ ...form, seoMeta: { ...form.seoMeta, keywords: e.target.value } })} />
            </div>
          </div>
        </Card>

        {/* 블록 빌더 */}
        <div className="lg:col-span-2">
          <Card title="블록 에디터">
            <div className="flex items-center gap-2 mb-4 flex-wrap">
              {BLOCK_TYPES.map(({ type, label, icon: Icon }) => (
                <Btn key={type} size="sm" variant="ghost" onClick={() => addBlock(type)}><Icon size={13} /> {label}</Btn>
              ))}
              <Btn size="sm" variant="ghost" disabled={!!aiBusy} onClick={genDraft}><Sparkles size={13} /> {aiBusy === 'draft' ? 'AI 초안…' : 'AI 초안 블록'}</Btn>
            </div>

            {form.blocks.length === 0 && (
              <div className="text-center text-slate-500 text-sm py-10 border border-dashed border-edge rounded-lg">
                블록을 추가하세요. (텍스트 / 이미지 / 상품 / 배너)
              </div>
            )}

            <div className="space-y-3">
              {form.blocks.map((b: Block, i: number) => (
                <div key={i} className="bg-panel border border-edge rounded-lg p-3">
                  <div className="flex items-center justify-between mb-2">
                    <span className="flex items-center gap-1.5 text-xs font-semibold text-brand">
                      <GripVertical size={13} className="text-slate-500" /> {b.type.toUpperCase()} <span className="text-slate-500">#{i + 1}</span>
                    </span>
                    <div className="flex items-center gap-2">
                      <button onClick={() => moveBlock(i, -1)} className="text-slate-500 hover:text-brand text-xs">▲</button>
                      <button onClick={() => moveBlock(i, 1)} className="text-slate-500 hover:text-brand text-xs">▼</button>
                      <button onClick={() => removeBlock(i)} className="text-rose-400 hover:text-rose-300"><Trash2 size={14} /></button>
                    </div>
                  </div>
                  <BlockEditor block={b} onChange={p => setBlock(i, p)} />
                </div>
              ))}
            </div>
            <details className="mt-4">
              <summary className="text-[11px] text-slate-500 cursor-pointer">블록 JSON 보기</summary>
              <pre className="mt-2 text-[11px] text-slate-400 bg-ink border border-edge rounded p-3 overflow-auto max-h-48">{JSON.stringify(form.blocks, null, 2)}</pre>
            </details>
          </Card>
        </div>
      </div>

      {showVersions && (
        <Modal title="버전 히스토리" onClose={() => setShowVersions(false)}>
          {versions.length === 0 ? <p className="text-slate-500 text-sm">버전 기록이 없습니다.</p> : (
            <ul className="divide-y divide-edge/50">
              {versions.map(v => (
                <li key={v.id ?? v.version} className="flex items-center justify-between py-2.5 text-sm">
                  <div>
                    <span className="font-medium">v{v.version}</span>
                    <span className="text-slate-400 ml-2">{v.title}</span>
                    <div className="text-[11px] text-slate-500">{v.createdAt ? new Date(v.createdAt).toLocaleString('ko-KR') : ''} · {v.createdBy || ''}</div>
                  </div>
                  <Btn size="sm" variant="ghost" onClick={() => doRollback(v.version)}><RotateCcw size={13} /> 롤백</Btn>
                </li>
              ))}
            </ul>
          )}
        </Modal>
      )}

      {showSchedule && (
        <Modal title="예약 게시" onClose={() => setShowSchedule(false)}>
          <Field label="게시 일시" hint="도래 시 스케줄러가 자동 PUBLISHED 처리합니다.">
            <input className="inp" type="datetime-local" value={schedAt} onChange={e => setSchedAt(e.target.value)} />
          </Field>
          <div className="flex justify-end gap-2 mt-5">
            <Btn variant="ghost" onClick={() => setShowSchedule(false)}>취소</Btn>
            <Btn onClick={doSchedule}>예약</Btn>
          </div>
        </Modal>
      )}
    </div>
  )
}

function BlockEditor({ block, onChange }: { block: Block; onChange: (p: object) => void }) {
  if (block.type === 'text')
    return <textarea className="inp" value={block.text || ''} onChange={e => onChange({ text: e.target.value })} placeholder="텍스트 내용" />
  if (block.type === 'image')
    return (
      <div className="space-y-2">
        <input className="inp" value={block.url || ''} onChange={e => onChange({ url: e.target.value })} placeholder="이미지 URL" />
        <input className="inp" value={block.alt || ''} onChange={e => onChange({ alt: e.target.value })} placeholder="대체 텍스트" />
      </div>
    )
  if (block.type === 'product')
    return (
      <div className="grid grid-cols-2 gap-2">
        <input className="inp" value={block.productId || ''} onChange={e => onChange({ productId: e.target.value })} placeholder="상품 ID" />
        <input className="inp" value={block.label || ''} onChange={e => onChange({ label: e.target.value })} placeholder="라벨" />
      </div>
    )
  if (block.type === 'banner')
    return (
      <div className="grid grid-cols-2 gap-2">
        <input className="inp" value={block.bannerId || ''} onChange={e => onChange({ bannerId: e.target.value })} placeholder="배너 ID" />
        <input className="inp" value={block.label || ''} onChange={e => onChange({ label: e.target.value })} placeholder="라벨" />
      </div>
    )
  return null
}
