import React, { useState, useEffect, useCallback, useRef } from 'react';
import PullToRefresh from '../../components/PullToRefresh';
import {
  getInstaStatus,
  instaCollectNews,
  instaExtractKeywords,
  getInstaKeywords,
  createInstaSlate,
  getInstaSlates,
  getInstaSlate,
  renderInstaSlate,
  deleteInstaSlate,
  getInstaAssetUrl,
  getInstaTask,
  getInstaPrompt,
  putInstaPrompt,
} from '../../api';
import './InstaCards.css';

/* ────────────────────── 유틸 ────────────────────── */
function fmtDate(iso) {
  if (!iso) return '';
  return new Date(iso).toLocaleDateString('ko-KR', {
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function StatusBadge({ status }) {
  return (
    <span className={`ic-status-badge ic-status-badge--${status || 'draft'}`}>
      {status || 'draft'}
    </span>
  );
}

/* ────────────────────── 폴링 훅 ────────────────────── */
function usePollTask(onDone) {
  const [taskId, setTaskId] = useState(null);
  const [task, setTask] = useState(null);
  const timer = useRef(null);

  useEffect(() => {
    if (!taskId) return;
    let cancelled = false;
    const poll = async () => {
      try {
        const t = await getInstaTask(taskId);
        if (cancelled) return;
        setTask(t);
        if (t.status === 'succeeded' || t.status === 'failed') {
          setTaskId(null);
          onDone?.(t);
        } else {
          timer.current = setTimeout(poll, 3000);
        }
      } catch {
        if (!cancelled) timer.current = setTimeout(poll, 3000);
      }
    };
    poll();
    return () => {
      cancelled = true;
      clearTimeout(timer.current);
    };
  }, [taskId]); // eslint-disable-line react-hooks/exhaustive-deps

  return {
    taskId,
    task,
    start: setTaskId,
    clear: () => { setTaskId(null); setTask(null); },
  };
}

/* ────────────────────── TaskStatusBox ────────────────────── */
function TaskStatusBox({ task }) {
  if (!task) return null;
  const pct = task.progress != null ? task.progress : (task.status === 'succeeded' ? 100 : 0);
  return (
    <div className="ic-task-status">
      <div className="ic-task-status__label">
        {task.status === 'succeeded' ? '완료' : task.status === 'failed' ? '실패' : '진행 중'}
      </div>
      <div className="ic-task-status__msg">{task.message || task.error || ''}</div>
      <div className="ic-task-status__progress">
        <div className="ic-task-status__fill" style={{ width: `${pct}%` }} />
      </div>
    </div>
  );
}

/* ══════════════════════════════════════════════════════════════════════════ */
export default function InstaCards() {
  const [status, setStatus] = useState(null);
  const [selectedSlateId, setSelectedSlateId] = useState(null);

  const loadStatus = useCallback(() => {
    return getInstaStatus().then(setStatus).catch(() => {});
  }, []);

  useEffect(() => {
    loadStatus();
  }, [loadStatus]);

  return (
    <PullToRefresh onRefresh={loadStatus}>
      <div className="ic">
        {/* 헤더 + 상태 배너 */}
        <header className="ic-header">
          <h1>Insta Cards</h1>
          {status && (
            <div className="ic-status-badges">
              <span className={`ic-badge ${status.naver_api ? 'ic-badge--on' : 'ic-badge--off'}`}>
                Naver {status.naver_api ? 'ON' : 'OFF'}
              </span>
              <span className={`ic-badge ${status.anthropic_api ? 'ic-badge--on' : 'ic-badge--off'}`}>
                AI {status.anthropic_api ? 'ON' : 'OFF'}
              </span>
            </div>
          )}
        </header>

        <div className="ic-layout">
          {/* 왼쪽: 트리거 + 키워드 */}
          <div>
            <TriggerPanel />
            <div style={{ height: 16 }} />
            <KeywordsPanel onCreateSlate={() => setSelectedSlateId(null)} />
          </div>

          {/* 오른쪽: 슬레이트 목록 + 상세 */}
          <div>
            <SlatesPanel
              selectedId={selectedSlateId}
              onSelect={setSelectedSlateId}
            />
          </div>
        </div>

        <PromptTemplatesEditor />
      </div>
    </PullToRefresh>
  );
}

/* ══════════════════════ 트리거 패널 ══════════════════════════════════════ */
function TriggerPanel() {
  const collectPoll = usePollTask();
  const keywordsPoll = usePollTask();

  async function handleCollect() {
    try {
      const res = await instaCollectNews();
      collectPoll.start(res.task_id);
    } catch (e) {
      alert('뉴스 수집 실패: ' + e.message);
    }
  }

  async function handleKeywords() {
    try {
      const res = await instaExtractKeywords();
      keywordsPoll.start(res.task_id);
    } catch (e) {
      alert('키워드 추출 실패: ' + e.message);
    }
  }

  const collectBusy = !!collectPoll.taskId;
  const kwBusy = !!keywordsPoll.taskId;

  return (
    <div className="ic-section">
      <p className="ic-section__title">트리거</p>
      <div className="ic-trigger-buttons">
        <button
          className="ic-btn ic-btn--primary"
          onClick={handleCollect}
          disabled={collectBusy}
        >
          {collectBusy && <span className="ic-spinner" />}
          뉴스 수집
        </button>
        <TaskStatusBox task={collectPoll.task} />
        <button
          className="ic-btn ic-btn--secondary"
          onClick={handleKeywords}
          disabled={kwBusy}
        >
          {kwBusy && <span className="ic-spinner" />}
          키워드 추출
        </button>
        <TaskStatusBox task={keywordsPoll.task} />
      </div>
    </div>
  );
}

/* ══════════════════════ 키워드 목록 ══════════════════════════════════════ */
const CATEGORIES = ['전체', 'economy', 'psychology', 'celebrity'];

function KeywordsPanel({ onCreateSlate }) {
  const [category, setCategory] = useState('전체');
  const [keywords, setKeywords] = useState([]);
  const [creating, setCreating] = useState(null); // keyword_id being created
  const slatePoll = usePollTask((t) => {
    if (t.status === 'succeeded') onCreateSlate?.();
    setCreating(null);
  });

  const load = useCallback(() => {
    const cat = category === '전체' ? undefined : category;
    getInstaKeywords({ category: cat }).then((r) => setKeywords(r.items || [])).catch(() => {});
  }, [category]);

  useEffect(() => { load(); }, [load]);

  async function handleCreate(kw) {
    if (creating) return;
    setCreating(kw.id);
    try {
      const res = await createInstaSlate({
        keyword: kw.keyword,
        category: kw.category,
        keyword_id: kw.id,
      });
      slatePoll.start(res.task_id);
    } catch (e) {
      alert('카드 생성 실패: ' + e.message);
      setCreating(null);
    }
  }

  return (
    <div className="ic-section">
      <p className="ic-section__title">트렌딩 키워드</p>

      {/* 카테고리 필터 */}
      <div className="ic-filter">
        {CATEGORIES.map((c) => (
          <button
            key={c}
            className={`ic-filter-btn ${category === c ? 'ic-filter-btn--active' : ''}`}
            onClick={() => setCategory(c)}
          >
            {c}
          </button>
        ))}
      </div>

      {slatePoll.task && <TaskStatusBox task={slatePoll.task} />}

      {keywords.length === 0 ? (
        <div className="ic-empty">키워드가 없습니다. 키워드 추출을 실행하세요.</div>
      ) : (
        <div className="ic-keywords">
          {keywords.map((kw) => (
            <div key={kw.id} className="ic-keyword-row">
              <span className="ic-keyword-row__kw">{kw.keyword}</span>
              <span className="ic-keyword-row__meta">
                {kw.category} · {kw.articles_count ?? 0}건
              </span>
              <span className="ic-keyword-row__score">{kw.score?.toFixed(1) ?? '-'}</span>
              <button
                className="ic-btn ic-btn--primary ic-btn--sm"
                onClick={() => handleCreate(kw)}
                disabled={!!creating}
              >
                {creating === kw.id ? <span className="ic-spinner" /> : '🎴'}
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ══════════════════════ 슬레이트 목록 ══════════════════════════════════ */
function SlatesPanel({ selectedId, onSelect }) {
  const [slates, setSlates] = useState([]);
  const [detail, setDetail] = useState(null);

  const loadSlates = useCallback(() => {
    getInstaSlates(50).then((r) => setSlates(r.items || [])).catch(() => {});
  }, []);

  useEffect(() => { loadSlates(); }, [loadSlates]);

  useEffect(() => {
    if (!selectedId) { setDetail(null); return; }
    getInstaSlate(selectedId).then(setDetail).catch(() => setDetail(null));
  }, [selectedId]);

  function handleSelect(id) {
    onSelect(id === selectedId ? null : id);
  }

  async function handleDelete(id) {
    if (!confirm('슬레이트를 삭제하시겠습니까?')) return;
    try {
      await deleteInstaSlate(id);
      if (selectedId === id) onSelect(null);
      loadSlates();
    } catch (e) {
      alert('삭제 실패: ' + e.message);
    }
  }

  async function handleRender(id) {
    try {
      const res = await renderInstaSlate(id);
      // Re-render is fire-and-forget from the panel; user can refresh detail
      alert('재렌더 요청 완료 (task: ' + res.task_id + ')');
      setTimeout(loadSlates, 3000);
    } catch (e) {
      alert('재렌더 실패: ' + e.message);
    }
  }

  return (
    <div>
      <div className="ic-section">
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 14 }}>
          <p className="ic-section__title" style={{ margin: 0, flex: 1 }}>슬레이트 목록</p>
          <button className="ic-btn ic-btn--secondary ic-btn--sm" onClick={loadSlates}>↻ 새로고침</button>
        </div>

        {slates.length === 0 ? (
          <div className="ic-empty">슬레이트가 없습니다. 카드를 생성해 보세요.</div>
        ) : (
          <div className="ic-slates-grid">
            {slates.map((s) => (
              <div
                key={s.id}
                className={`ic-slate-card ${selectedId === s.id ? 'ic-slate-card--active' : ''}`}
                onClick={() => handleSelect(s.id)}
              >
                {s.status === 'rendered' || s.status === 'sent' ? (
                  <img
                    className="ic-slate-thumb"
                    src={getInstaAssetUrl(s.id, 1)}
                    alt={s.keyword}
                    loading="lazy"
                  />
                ) : (
                  <div className="ic-slate-thumb--placeholder">🎴</div>
                )}
                <div className="ic-slate-card__info">
                  <div className="ic-slate-card__kw">{s.keyword}</div>
                  <div className="ic-slate-card__meta">
                    <span className="ic-slate-card__date">{fmtDate(s.created_at)}</span>
                    <StatusBadge status={s.status} />
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* 슬레이트 상세 */}
      {detail && (
        <SlateDetail
          slate={detail}
          onDelete={() => handleDelete(detail.id)}
          onRender={() => handleRender(detail.id)}
        />
      )}
    </div>
  );
}

/* ══════════════════════ 슬레이트 상세 ══════════════════════════════════ */
function SlateDetail({ slate, onDelete, onRender }) {
  const pages = slate.assets || [];
  const pageCount = pages.length > 0 ? pages.length : 10;

  function copyCaption() {
    const text = [slate.suggested_caption, slate.hashtags?.join(' ')].filter(Boolean).join('\n\n');
    navigator.clipboard.writeText(text).then(() => alert('클립보드에 복사되었습니다!'));
  }

  return (
    <div className="ic-detail">
      <div className="ic-detail__header">
        <div className="ic-detail__title">
          {slate.keyword}
          <span style={{ marginLeft: 8 }}><StatusBadge status={slate.status} /></span>
        </div>
        <div className="ic-detail__actions">
          <button className="ic-btn ic-btn--secondary ic-btn--sm" onClick={onRender}>재렌더</button>
          <button className="ic-btn ic-btn--danger ic-btn--sm" onClick={onDelete}>삭제</button>
        </div>
      </div>

      {/* 페이지 이미지 스트립 */}
      {(slate.status === 'rendered' || slate.status === 'sent') ? (
        <div className="ic-pages-strip">
          {Array.from({ length: pageCount }, (_, i) => i + 1).map((page) => (
            <img
              key={page}
              className="ic-page-img"
              src={getInstaAssetUrl(slate.id, page)}
              alt={`Page ${page}`}
              loading="lazy"
            />
          ))}
        </div>
      ) : (
        <div className="ic-empty" style={{ padding: '20px 0' }}>
          {slate.status === 'failed' ? '렌더 실패 — 재렌더를 시도하세요.' : '렌더링 전입니다.'}
        </div>
      )}

      {/* 캡션 */}
      {slate.suggested_caption && (
        <div className="ic-caption-box">
          <div className="ic-caption-box__label">
            캡션
            <button
              className="ic-btn ic-btn--secondary ic-btn--sm"
              style={{ marginLeft: 8 }}
              onClick={copyCaption}
            >
              복사
            </button>
          </div>
          <div className="ic-caption-text">{slate.suggested_caption}</div>
          {slate.hashtags?.length > 0 && (
            <div className="ic-hashtags" style={{ marginTop: 8 }}>
              {slate.hashtags.join(' ')}
            </div>
          )}
        </div>
      )}

      {/* 커버 카피 / 바디 카피 */}
      {slate.cover_copy && (
        <div className="ic-caption-box">
          <div className="ic-caption-box__label">커버 카피</div>
          <div className="ic-caption-text">{slate.cover_copy}</div>
        </div>
      )}
    </div>
  );
}

/* ══════════════════════ 프롬프트 템플릿 에디터 ══════════════════════════ */
const PROMPT_NAMES = ['slate_writer', 'category_seeds'];

function PromptTemplatesEditor() {
  const [prompts, setPrompts] = useState({});
  const [drafts, setDrafts] = useState({});
  const [saving, setSaving] = useState({});

  useEffect(() => {
    PROMPT_NAMES.forEach((name) => {
      getInstaPrompt(name)
        .then((p) => {
          setPrompts((prev) => ({ ...prev, [name]: p }));
          setDrafts((prev) => ({ ...prev, [name]: p.template }));
        })
        .catch(() => {
          setPrompts((prev) => ({ ...prev, [name]: null }));
          setDrafts((prev) => ({ ...prev, [name]: '' }));
        });
    });
  }, []);

  async function handleSave(name) {
    setSaving((prev) => ({ ...prev, [name]: true }));
    try {
      const updated = await putInstaPrompt(name, drafts[name] || '', prompts[name]?.description || '');
      setPrompts((prev) => ({ ...prev, [name]: updated }));
      alert(`${name} 저장 완료`);
    } catch (e) {
      alert('저장 실패: ' + e.message);
    } finally {
      setSaving((prev) => ({ ...prev, [name]: false }));
    }
  }

  return (
    <div className="ic-prompt-editor" style={{ marginTop: 24 }}>
      <p className="ic-prompt-editor__title">프롬프트 템플릿</p>
      {PROMPT_NAMES.map((name) => (
        <div key={name} className="ic-prompt-block">
          <div className="ic-prompt-block__head">
            <span className="ic-prompt-block__name">{name}</span>
            {prompts[name]?.updated_at && (
              <span className="ic-prompt-block__date">
                최종 수정: {fmtDate(prompts[name].updated_at)}
              </span>
            )}
          </div>
          {prompts[name]?.description && (
            <div style={{ fontSize: '0.75rem', color: 'rgba(255,255,255,.4)', marginBottom: 6 }}>
              {prompts[name].description}
            </div>
          )}
          <textarea
            className="ic-prompt-textarea"
            value={drafts[name] ?? ''}
            onChange={(e) => setDrafts((prev) => ({ ...prev, [name]: e.target.value }))}
            placeholder={`${name} 템플릿을 입력하세요...`}
          />
          <div className="ic-prompt-save-row">
            <button
              className="ic-btn ic-btn--primary ic-btn--sm"
              onClick={() => handleSave(name)}
              disabled={saving[name]}
            >
              {saving[name] ? <span className="ic-spinner" /> : null}
              저장
            </button>
          </div>
        </div>
      ))}
    </div>
  );
}
