/**
 * 검증게시판 — 좌 목록 + 우 상세
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import BuilderPageShell from './layout/BuilderPageShell';
import VerificationIssueListPanel from './verificationBoard/VerificationIssueListPanel';
import VerificationIssueDetailPanel from './verificationBoard/VerificationIssueDetailPanel';
import VerificationIssueFormModal from './verificationBoard/VerificationIssueFormModal';
import type { Theme } from '../types';
import type { VerificationIssueStage } from '../utils/verificationBoardStages';
import {
  deleteVerificationIssue,
  deleteVerificationIssueImage,
  loadVerificationIssues,
  saveVerificationIssue,
  uploadVerificationIssueImages,
  type VerificationIssueDto,
} from '../utils/verificationBoardApi';
import { prepareImagesForUpload } from '../utils/clipboardImageFiles';
import '../styles/verificationBoard.css';

interface Props {
  theme?: Theme;
  focusIssueId?: number | null;
  onFocusIssueConsumed?: () => void;
}

const IconAdd = () => (
  <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
    <path d="M9 3v12M3 9h12" />
  </svg>
);

const IconEdit = () => (
  <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12.5 2.5l3 3L6 15H3v-3L12.5 2.5z" />
  </svg>
);

const IconDelete = () => (
  <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M3 5h12M7 5V3h4v2M6 5l.5 10h5L12 5" />
  </svg>
);

const VerificationBoardPage: React.FC<Props> = ({
  theme = 'dark',
  focusIssueId = null,
  onFocusIssueConsumed,
}) => {
  const [issues, setIssues] = useState<VerificationIssueDto[]>([]);
  const [selectedId, setSelectedId] = useState<number | null>(null);
  const [stageFilter, setStageFilter] = useState<VerificationIssueStage | ''>('');
  const [searchQuery, setSearchQuery] = useState('');
  const [loading, setLoading] = useState(true);
  const [modalOpen, setModalOpen] = useState(false);
  const [editTarget, setEditTarget] = useState<VerificationIssueDto | null>(null);
  const [saving, setSaving] = useState(false);
  const [detailSaving, setDetailSaving] = useState(false);
  const [attachmentsRefreshKey, setAttachmentsRefreshKey] = useState(0);

  const reload = useCallback(async (stage?: VerificationIssueStage | '') => {
    setLoading(true);
    try {
      const list = await loadVerificationIssues(stage ?? stageFilter);
      setIssues(list);
      setSelectedId(prev => {
        if (prev != null && list.some(i => i.id === prev)) return prev;
        return list[0]?.id ?? null;
      });
    } catch (e) {
      console.warn('[VerificationBoard] load', e);
      window.alert('검증 이슈 목록을 불러오지 못했습니다.');
    } finally {
      setLoading(false);
    }
  }, [stageFilter]);

  useEffect(() => {
    void reload(stageFilter);
  }, [stageFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (focusIssueId == null) return;
    setSelectedId(focusIssueId);
    setStageFilter('');
    onFocusIssueConsumed?.();
  }, [focusIssueId, onFocusIssueConsumed]);

  const selected = useMemo(
    () => issues.find(i => i.id === selectedId) ?? null,
    [issues, selectedId],
  );

  const handleSelect = useCallback((issue: VerificationIssueDto) => {
    if (issue.id != null) setSelectedId(issue.id);
  }, []);

  const handleAdd = useCallback(() => {
    setEditTarget(null);
    setModalOpen(true);
  }, []);

  const handleEdit = useCallback(() => {
    if (!selected) {
      window.alert('수정할 이슈를 선택하세요.');
      return;
    }
    setEditTarget(selected);
    setModalOpen(true);
  }, [selected]);

  const handleDelete = useCallback(async () => {
    if (!selected?.id) {
      window.alert('삭제할 이슈를 선택하세요.');
      return;
    }
    if (!window.confirm(`「${selected.title}」 이슈를 삭제할까요?`)) return;
    try {
      await deleteVerificationIssue(selected.id);
      await reload(stageFilter);
    } catch (e) {
      console.warn('[VerificationBoard] delete', e);
      window.alert('삭제에 실패했습니다.');
    }
  }, [selected, reload, stageFilter]);

  const handleSave = useCallback(async (dto: VerificationIssueDto, pendingImages: File[]) => {
    setSaving(true);
    try {
      const saved = await saveVerificationIssue(dto);
      if (pendingImages.length > 0 && saved.id != null) {
        await uploadVerificationIssueImages(saved.id, pendingImages);
      }
      setModalOpen(false);
      setEditTarget(null);
      setAttachmentsRefreshKey(k => k + 1);
      await reload(stageFilter);
      if (saved.id != null) setSelectedId(saved.id);
    } catch (e) {
      console.warn('[VerificationBoard] save', e);
      window.alert('저장에 실패했습니다.');
    } finally {
      setSaving(false);
    }
  }, [reload, stageFilter]);

  const handleDetailSave = useCallback(async (
    dto: VerificationIssueDto,
    pendingImages: File[],
    pendingDeleteIds: number[],
  ) => {
    if (dto.id == null) return;
    setDetailSaving(true);
    try {
      const saved = await saveVerificationIssue(dto);
      const issueId = saved.id ?? dto.id;
      for (const imageId of pendingDeleteIds) {
        await deleteVerificationIssueImage(issueId, imageId);
      }
      if (pendingImages.length > 0) {
        const prepared = await prepareImagesForUpload(pendingImages);
        await uploadVerificationIssueImages(issueId, prepared);
      }
      setAttachmentsRefreshKey(k => k + 1);
      await reload(stageFilter);
      if (issueId != null) setSelectedId(issueId);
    } catch (e) {
      console.warn('[VerificationBoard] detail save', e);
      window.alert('저장에 실패했습니다.');
    } finally {
      setDetailSaving(false);
    }
  }, [reload, stageFilter]);

  return (
    <>
      <BuilderPageShell
        theme={theme}
        title="검증게시판"
        subtitle="Golden QA · Verification Board"
        pageClassName="bps-page--vbd"
        loading={loading}
        loadingText="검증 이슈 로딩 중…"
        headerActions={(
          <div className="vbd-header-actions">
            <button type="button" className="vbd-icon-btn" onClick={handleAdd} title="이슈 추가">
              <IconAdd />
              <span className="vbd-icon-btn-label">추가</span>
            </button>
            <button
              type="button"
              className="vbd-icon-btn"
              onClick={handleEdit}
              disabled={!selected}
              title="이슈 수정"
            >
              <IconEdit />
              <span className="vbd-icon-btn-label">수정</span>
            </button>
            <button
              type="button"
              className="vbd-icon-btn vbd-icon-btn--danger"
              onClick={() => void handleDelete()}
              disabled={!selected}
              title="이슈 삭제"
            >
              <IconDelete />
              <span className="vbd-icon-btn-label">삭제</span>
            </button>
          </div>
        )}
        leftStorageKey="vbd-left-width"
        leftDefaultWidth={320}
        leftCollapsedStorageKey="vbd-left-open"
        collapsiblePanels
        leftTitle="검증 이슈"
        left={(
          <VerificationIssueListPanel
            issues={issues}
            selectedId={selectedId}
            stageFilter={stageFilter}
            searchQuery={searchQuery}
            onStageFilterChange={setStageFilter}
            onSearchChange={setSearchQuery}
            onSelect={handleSelect}
          />
        )}
        center={(
          <VerificationIssueDetailPanel
            issue={selected}
            attachmentsRefreshKey={attachmentsRefreshKey}
            saving={detailSaving}
            onSave={handleDetailSave}
          />
        )}
      />

      <VerificationIssueFormModal
        open={modalOpen}
        initial={editTarget}
        saving={saving}
        onSave={(dto, pendingImages) => void handleSave(dto, pendingImages)}
        onCancel={() => { setModalOpen(false); setEditTarget(null); }}
      />
    </>
  );
};

export default VerificationBoardPage;
