/**
 * 검증게시판 — 우측 이슈 상세 (인라인 편집 + 저장)
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import type { VerificationIssueDto } from '../../utils/verificationBoardApi';
import {
  VERIFICATION_ISSUE_STAGES,
  stageColor,
  type VerificationIssueStage,
} from '../../utils/verificationBoardStages';
import ReproductionPathInput from './ReproductionPathInput';
import VerificationIssueCommentsSection from './VerificationIssueCommentsSection';
import VerificationIssueAttachmentsSection from './VerificationIssueAttachmentsSection';
import { formatIsoDateTime } from '../../utils/timezone';

interface Props {
  issue: VerificationIssueDto | null;
  attachmentsRefreshKey?: number;
  saving?: boolean;
  onSave?: (
    dto: VerificationIssueDto,
    pendingImages: File[],
  ) => void | Promise<void>;
  onAttachmentsChanged?: () => void;
}

const VerificationIssueDetailPanel: React.FC<Props> = ({
  issue,
  attachmentsRefreshKey = 0,
  saving = false,
  onSave,
  onAttachmentsChanged,
}) => {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [reproductionPath, setReproductionPath] = useState('');
  const [stage, setStage] = useState<VerificationIssueStage>('REGISTERED');
  const [pendingImages, setPendingImages] = useState<File[]>([]);

  const resetFromIssue = useCallback((src: VerificationIssueDto) => {
    setTitle(src.title ?? '');
    setContent(src.content ?? '');
    setReproductionPath(src.reproductionPath ?? '');
    setStage(src.stage ?? 'REGISTERED');
    setPendingImages([]);
  }, []);

  useEffect(() => {
    if (issue) resetFromIssue(issue);
  }, [issue?.id, attachmentsRefreshKey, resetFromIssue]); // eslint-disable-line react-hooks/exhaustive-deps

  const dirty = useMemo(() => {
    if (!issue) return false;
    const pathTrimmed = reproductionPath.trim();
    const issuePath = (issue.reproductionPath ?? '').trim();
    return (
      title.trim() !== (issue.title ?? '').trim()
      || content.trim() !== (issue.content ?? '').trim()
      || pathTrimmed !== issuePath
      || stage !== issue.stage
      || pendingImages.length > 0
    );
  }, [issue, title, content, reproductionPath, stage, pendingImages]);

  const handleCancel = () => {
    if (issue) resetFromIssue(issue);
  };

  const handleSave = () => {
    if (!issue?.id || !onSave) return;
    const trimmed = title.trim();
    if (!trimmed) {
      window.alert('제목을 입력하세요.');
      return;
    }
    const pathTrimmed = reproductionPath.trim();
    void onSave(
      {
        id: issue.id,
        title: trimmed,
        content: content.trim(),
        reproductionPath: pathTrimmed || undefined,
        stage,
      },
      pendingImages,
    );
  };

  if (!issue) {
    return (
      <div className="vbd-detail vbd-detail--empty">
        <p>좌측 목록에서 검증 이슈를 선택하세요.</p>
      </div>
    );
  }

  return (
    <div className="vbd-detail">
      <div className="vbd-detail-scroll">
        <div className="vbd-detail-title-row">
          <input
            type="text"
            className="vbd-detail-title-input"
            value={title}
            onChange={e => setTitle(e.target.value)}
            maxLength={300}
            disabled={saving}
            placeholder="검증 이슈 제목"
            aria-label="제목"
          />
          <select
            value={stage}
            onChange={e => setStage(e.target.value as VerificationIssueStage)}
            disabled={saving}
            className="vbd-detail-stage-select"
            aria-label="단계"
            title="처리 단계"
            style={{
              borderColor: `${stageColor(stage)}55`,
              color: stageColor(stage),
              backgroundColor: `${stageColor(stage)}14`,
            }}
          >
            {VERIFICATION_ISSUE_STAGES.map(s => (
              <option key={s.value} value={s.value}>{s.label}</option>
            ))}
          </select>
        </div>

        <div className="vbd-detail-meta">
          <span>등록 {formatIsoDateTime(issue.createdAt)}</span>
          <span>수정 {formatIsoDateTime(issue.updatedAt)}</span>
        </div>

        <label className="vbd-field">
          <span className="vbd-field-label">재현경로</span>
          <ReproductionPathInput
            value={reproductionPath}
            onChange={setReproductionPath}
            disabled={saving}
          />
        </label>

        <label className="vbd-field vbd-field--grow">
          <span className="vbd-field-label">내용</span>
          <textarea
            className="vbd-detail-content-input"
            value={content}
            onChange={e => setContent(e.target.value)}
            rows={12}
            disabled={saving}
            placeholder="문제점·재현 방법·기대 결과 등"
          />
        </label>

        {issue.id != null && (
          <VerificationIssueAttachmentsSection
            key={`${issue.id}-${attachmentsRefreshKey}`}
            issueId={issue.id}
            deferUpload
            draftFiles={pendingImages}
            onDraftFilesChange={setPendingImages}
            disabled={saving}
            onAttachmentsChanged={onAttachmentsChanged}
          />
        )}

        {issue.id != null && (
          <VerificationIssueCommentsSection issueId={issue.id} />
        )}
      </div>

      <div className="vbd-detail-footer">
        <span className="vbd-detail-dirty-hint">
          {dirty ? '저장하지 않은 변경 사항이 있습니다.' : ''}
        </span>
        <div className="vbd-detail-footer-actions">
          <button
            type="button"
            className="vbd-btn"
            onClick={handleCancel}
            disabled={saving || !dirty}
          >
            취소
          </button>
          <button
            type="button"
            className="vbd-btn vbd-btn--primary"
            onClick={handleSave}
            disabled={saving || !dirty}
          >
            {saving ? '저장 중…' : '저장'}
          </button>
        </div>
      </div>
    </div>
  );
};

export default VerificationIssueDetailPanel;
