// kanban.jsx — T-04 Stage 02 본격 주행 (칸반)

const { Icon, Pill, Tag, Avatar, Button, Progress } = window.RAlly;

const INITIAL_CARDS = [
  // 시작 전
  { id: 1, col: 'todo', cat: 'sop',   title: 'SOP-PR-027 변경 관리 절차', owner: '박지', d: null },
  { id: 2, col: 'todo', cat: 'tech',  title: '설계 검증 보고서 §5 보안 평가', owner: '김민', d: null },
  { id: 3, col: 'todo', cat: 'risk',  title: 'R-022 외부 API 응답 지연 평가', owner: '이수', d: null },
  { id: 4, col: 'todo', cat: 'sop',   title: 'SOP-QA-021 부적합 처리', owner: '박지', d: 'D-21' },
  { id: 5, col: 'todo', cat: 'capa',  title: 'CAPA-2026-005 예방조치 계획', owner: '이수', d: 'D-18' },

  // 작성 중
  { id: 10, col: 'doing', cat: 'risk', title: 'R-018 인터페이스 오작동 통제 방안', owner: '박지', d: 'D-2', urgent: true, comments: 3 },
  { id: 11, col: 'doing', cat: 'sop',  title: 'SOP-QA-014 검증 절차서 v1.4', owner: '박지', d: 'D-3', urgent: true, comments: 5 },
  { id: 12, col: 'doing', cat: 'tech', title: '설계 검증 보고서 §4.2 임상 데이터', owner: '김민', d: 'D-5', comments: 2, hasAi: true },
  { id: 13, col: 'doing', cat: 'risk', title: 'R-021 잘못된 진단 결과 출력', owner: '박지', d: 'D-8', comments: 1 },
  { id: 14, col: 'doing', cat: 'sop',  title: 'SOP-PR-018 제품 출하 검사', owner: '이수', d: 'D-14', comments: 0 },

  // 검토 중
  { id: 20, col: 'review', cat: 'tech', title: '기술문서 §2 제품 설명서', owner: '김민', d: 'D-4', reviewer: '혜', reviewerCoral: true, comments: 4 },
  { id: 21, col: 'review', cat: 'risk', title: '위험관리 보고서 v2.0', owner: '박지', d: 'D-6', reviewer: '혜', reviewerCoral: true, comments: 8 },
  { id: 22, col: 'review', cat: 'sop',  title: 'SOP-QA-009 내부 감사', owner: '이수', d: 'D-9', reviewer: '대표', comments: 1 },
  { id: 23, col: 'review', cat: 'tech', title: '설계 입력·출력 매트릭스 v1.2', owner: '김민', d: 'D-11', reviewer: '박지', comments: 2 },

  // 완주
  { id: 30, col: 'done', cat: 'tech', title: '기술문서 §3 임상 평가', owner: '김민', completedAt: '오늘' },
  { id: 31, col: 'done', cat: 'sop',  title: 'SOP-DE-005 설계 입력 정의', owner: '박지', completedAt: '5/10' },
  { id: 32, col: 'done', cat: 'risk', title: 'R-001~017 초기 위험 식별', owner: '박지', completedAt: '5/8' },
  { id: 33, col: 'done', cat: 'capa', title: 'CAPA-2026-001 효과성 검증', owner: '이수', completedAt: '5/5' },
];

const COLUMNS = [
  { key: 'todo',   icon: '📋', label: '시작 전', tone: 'default' },
  { key: 'doing',  icon: '🏃', label: '작성 중', tone: 'coral' },
  { key: 'review', icon: '👀', label: '검토 중', tone: 'amber' },
  { key: 'done',   icon: '🏁', label: '완주',    tone: 'green' },
];

const CAT_META = {
  sop:  { label: 'SOP',     variant: 'default' },
  risk: { label: '위험관리', variant: 'default' },
  tech: { label: '기술문서', variant: 'default' },
  capa: { label: 'CAPA',     variant: 'default' },
};

const getTrackId = () => (typeof window !== 'undefined' && window.__RALLY_TRACK) || null;

// 선택된 트랙이 없으면 실제 생성 트랙(가장 최근·문서 보유)을 기본으로 해석
const resolveTrackId = () => {
  const t = getTrackId();
  if (t) return Promise.resolve(t);
  return fetch('/api/tracks').then((r) => r.json()).then((d) => {
    const tracks = d.tracks || [];
    // profile(실제 생성) 보유 트랙 우선, 없으면 마지막(최신) 트랙
    const real = tracks.filter((x) => x.profile);
    const pick = (real.length ? real : tracks).slice(-1)[0];
    const id = pick ? pick.id : 1;
    if (typeof window !== 'undefined') window.__RALLY_TRACK = id;
    return id;
  }).catch(() => 1);
};

// 백엔드 카드 → 렌더 카드 매핑
const mapCard = (d) => ({
  id: d.id, col: d.kanban_col, cat: d.category, title: d.name,
  owner: d.owner_initials || (d.author || '').slice(0, 2),
  d: d.deadline, reviewer: d.reviewer, reviewerCoral: d.reviewer === '혜',
  comments: d.comments, completedAt: d.kanban_col === 'done' ? '완주' : null,
  realgrade: !!d.realgrade, docType: d.doc_type || null,
  ownerRole: d.owner_role || null, ownerRoleLabel: d.owner_role_label || null,
  urgent: d.deadline && /^D-\d+$/.test(d.deadline) && parseInt(d.deadline.slice(2)) <= 3,
});

const Kanban = ({ go }) => {
  const [cards, setCards] = React.useState([]);
  const [draggingId, setDraggingId] = React.useState(null);
  const [dropCol, setDropCol] = React.useState(null);
  const [activeFilters, setActiveFilters] = React.useState(new Set(['sop', 'risk', 'tech', 'capa']));
  const [trackName, setTrackName] = React.useState('');
  // 로그인 사용자 역할 — 개발자(AUTHOR)면 '내 문서만'(개발 문서) 토글 제공, 기본 ON
  const me = (window.RAlly.getUser && window.RAlly.getUser()) || null;
  const isAuthor = !!(me && me.role === 'AUTHOR');
  const [mineOnly, setMineOnly] = React.useState(isAuthor);

  const loadBoard = React.useCallback(() => {
    resolveTrackId().then((tid) => fetch('/api/track/' + tid + '/kanban'))
      .then((r) => r.json())
      .then((d) => {
        const all = [];
        (d.columns || []).forEach((col) => (d.board[col] || []).forEach((c) => all.push(mapCard(c))));
        setCards(all);
        if (d.track && d.track.name) setTrackName(d.track.name);
      })
      .catch(() => {});
  }, []);
  React.useEffect(() => { loadBoard(); }, [loadBoard]);

  const toggleFilter = (cat) => {
    const next = new Set(activeFilters);
    if (next.has(cat)) next.delete(cat); else next.add(cat);
    setActiveFilters(next);
  };

  const onDragStart = (e, id) => {
    setDraggingId(id);
    e.dataTransfer.effectAllowed = 'move';
    try { e.dataTransfer.setData('text/plain', String(id)); } catch (_) {}
  };
  const onDragEnd = () => { setDraggingId(null); setDropCol(null); };

  const onDragOverCol = (e, col) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    if (dropCol !== col) setDropCol(col);
  };
  const onDropCol = (e, col) => {
    e.preventDefault();
    if (draggingId == null) return;
    const id = draggingId;
    const prevCol = (cards.find((c) => c.id === id) || {}).col;
    setCards((prev) => prev.map((c) => c.id === id ? { ...c, col, completedAt: col === 'done' ? '완주' : null } : c));
    setDraggingId(null);
    setDropCol(null);
    // 백엔드 상태 전이 + 승인 게이트 — 행위자·역할은 서버 세션에서 도출(위조 방지)
    fetch('/api/kanban/move', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ doc_id: id, col }),
    })
      .then((r) => r.json())
      .then((d) => {
        if (!d.ok) {
          alert('이동 거부 — ' + (d.error || '권한'));
          loadBoard(); // 낙관적 이동 되돌림
        }
      })
      .catch(() => loadBoard());
  };

  const visible = cards.filter((c) =>
    activeFilters.has(c.cat) && (!(isAuthor && mineOnly) || c.ownerRole === 'developer'));

  return (
    <div className="page">
      {/* Header */}
      <div className="page__head">
        <div>
          <div className="row" style={{ gap: 8, marginBottom: 6, fontSize: 12, color: 'var(--ink-3)' }}>
            <span
              onClick={() => go('track')}
              style={{ cursor: 'pointer', fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase', fontSize: 11 }}
              onMouseEnter={(e) => e.currentTarget.style.color = 'var(--coral)'}
              onMouseLeave={(e) => e.currentTarget.style.color = 'var(--ink-3)'}
            >← {trackName || '트랙'}</span>
            <Icon name="chev_right" size={11} />
            <Pill variant="coral">STAGE 02 · 본격 주행</Pill>
          </div>
          <div className="page__title">문서, 한 구간씩 같이 뛰어요</div>
          <div className="page__sub">SOP · 위험관리 · 기술문서 · CAPA를 한 보드에서 관리. 카드를 드래그해서 상태를 옮길 수 있어요.</div>
        </div>
        <div className="row">
          {isAuthor && (
            <FilterChip active={mineOnly} onClick={() => setMineOnly((v) => !v)}>
              {mineOnly ? '내 문서만' : '전체 문서'}
            </FilterChip>
          )}
          {me && (
            <span
              title="승인 게이트는 로그인 세션의 역할로 판정됩니다(화면에서 바꿀 수 없습니다)."
              style={{ fontSize: 12, padding: '7px 10px', borderRadius: 8, border: '1px solid var(--line)', color: 'var(--ink-2)' }}
            >{me.name} · {me.roleLabel || me.role}</span>
          )}
          <Button variant="ghost" icon="filter">필터</Button>
          <Button variant="primary" icon="plus">문서 추가</Button>
        </div>
      </div>

      {/* Filter bar */}
      <div className="row" style={{ marginBottom: 16, gap: 10, flexWrap: 'wrap' }}>
        <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.10em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>카테고리</span>
        {Object.entries(CAT_META).map(([key, meta]) => {
          const active = activeFilters.has(key);
          const count = cards.filter((c) => c.cat === key).length;
          return (
            <FilterChip key={key} active={active} onClick={() => toggleFilter(key)}>
              {meta.label} · {count}
            </FilterChip>
          );
        })}
        <span style={{ width: 1, height: 18, background: 'var(--line)', margin: '0 6px' }} />
        <FilterChip>담당: 모두</FilterChip>
        <FilterChip>우선순위</FilterChip>
        <span style={{ flex: 1 }} />
        <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>총 <strong>{visible.length}</strong>개 표시 중</span>
      </div>

      {/* Board */}
      <div className="board">
        {COLUMNS.map((col) => {
          const colCards = visible.filter((c) => c.col === col.key);
          return (
            <div
              key={col.key}
              className={'col' + (dropCol === col.key && draggingId != null ? ' col--drop' : '')}
              onDragOver={(e) => onDragOverCol(e, col.key)}
              onDragLeave={(e) => { if (e.currentTarget === e.target) setDropCol(null); }}
              onDrop={(e) => onDropCol(e, col.key)}
            >
              <div className="col__head">
                <div className="col__title">
                  <span style={{ fontSize: 14 }}>{col.icon}</span>
                  {col.label}
                </div>
                <span className="col__count">{colCards.length}</span>
              </div>
              {colCards.map((card) => (
                <KCard
                  key={card.id}
                  card={card}
                  dragging={draggingId === card.id}
                  onDragStart={(e) => onDragStart(e, card.id)}
                  onDragEnd={onDragEnd}
                  onClick={() => { window.__RALLY_DOC = card.id; window.__RALLY_DOC_TYPE = card.docType || null; go('editor'); }}
                />
              ))}
              <div
                className="row"
                style={{
                  border: '1px dashed var(--line-2)',
                  borderRadius: 8,
                  padding: '10px 12px',
                  color: 'var(--ink-3)',
                  fontSize: 12,
                  gap: 6,
                  cursor: 'pointer',
                  justifyContent: 'center',
                }}
              >
                <Icon name="plus" size={13} /> 카드 추가
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

const FilterChip = ({ active, onClick, children }) => (
  <button
    onClick={onClick}
    style={{
      height: 28,
      padding: '0 12px',
      borderRadius: 999,
      border: '1px solid ' + (active ? 'var(--navy)' : 'var(--line)'),
      background: active ? 'var(--navy)' : 'var(--surface)',
      color: active ? 'var(--on-navy)' : 'var(--ink-2)',
      fontSize: 12,
      fontWeight: 600,
      cursor: 'pointer',
      transition: 'all 180ms',
      whiteSpace: 'nowrap',
    }}
  >
    {children}
  </button>
);

const KCard = ({ card, dragging, onDragStart, onDragEnd, onClick }) => {
  const isUrgent = card.urgent;
  return (
    <div
      className={'kcard' + (isUrgent ? ' kcard--urgent' : '') + (dragging ? ' kcard--dragging' : '')}
      draggable
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      onClick={onClick}
    >
      <div className="kcard__row">
        <Tag>{CAT_META[card.cat].label}</Tag>
        {card.ownerRoleLabel && (
          <Pill variant={card.ownerRole === 'developer' ? 'navy' : 'default'} title="작성 담당 역할">
            {card.ownerRoleLabel}
          </Pill>
        )}
        {card.d && (
          <Pill variant={card.d.startsWith('D-') && parseInt(card.d.slice(2)) <= 3 ? 'red' : 'default'} className="tabular">{card.d}</Pill>
        )}
        {card.realgrade && (
          <Pill variant="coral" className="row" style={{ gap: 4 }} title="품목 정보로 실제 심사 수준 자동 생성됨">
            <Icon name="sparkles" size={10} /> 실제수준
          </Pill>
        )}
        <span style={{ marginLeft: 'auto', color: 'var(--ink-4)' }}>
          <Icon name="dots" size={14} />
        </span>
      </div>
      <div className="kcard__title">{card.title}</div>
      <div className="kcard__meta">
        <Avatar initials={card.owner} size="sm" />
        {card.reviewer && (
          <>
            <Icon name="arrow_right" size={11} />
            <Avatar initials={card.reviewer} size="sm" variant={card.reviewerCoral ? 'coral' : ''} title="검토자" />
          </>
        )}
        {card.comments != null && (
          <span className="row" style={{ gap: 3, marginLeft: 'auto', fontSize: 11 }}>
            <Icon name="message" size={11} /> {card.comments}
          </span>
        )}
        {card.completedAt && (
          <span style={{ marginLeft: 'auto', fontSize: 11, color: 'var(--green)', fontWeight: 600 }}>
            <Icon name="check" size={11} style={{ marginRight: 3, display: 'inline-block', verticalAlign: -2 }} />
            {card.completedAt}
          </span>
        )}
      </div>
    </div>
  );
};

window.RAlly.Kanban = Kanban;
