/**
 * 신고 등록 페이지 JavaScript
 * 흐름: 유형(1) → 위치(2) → 프로젝트(3) → 카테고리/항목(4) → 사진/상세(5) → 제출
 * URL 파라미터 ?type=nonconformity|safety|facility 로 유형 사전 선택 지원
 */

// API 설정
const API_BASE = window.API_BASE_URL || 'http://localhost:30105/api';

// 상태 변수
let selectedFactoryId = null;
let selectedWorkplaceId = null;
let selectedWorkplaceName = null;
let selectedType = null; // 'nonconformity' | 'safety' | 'facility'
let selectedCategoryId = null;
let selectedCategoryName = null;
let selectedItemId = null;
let selectedProjectId = null; // 선택된 프로젝트 ID
let selectedTbmSessionId = null;
let selectedVisitRequestId = null;
let projectSelected = false; // 프로젝트 선택 완료 여부
let photos = [null, null, null, null, null];
let customItemName = null;

// 지도 관련 변수
let canvas, ctx, canvasImage;
let mapRegions = [];
let todayWorkers = [];
let todayVisitors = [];

// 프로젝트 관련 변수
let allProjects = []; // 전체 활성 프로젝트 목록

// DOM 요소
let factorySelect, issueMapCanvas;
let photoInput, currentPhotoIndex;

// 초기화
document.addEventListener('DOMContentLoaded', async () => {
  factorySelect = document.getElementById('factorySelect');
  issueMapCanvas = document.getElementById('issueMapCanvas');
  photoInput = document.getElementById('photoInput');

  canvas = issueMapCanvas;
  ctx = canvas.getContext('2d');

  setupEventListeners();

  // 프로젝트 먼저 로드 후 공장 로드 (공장 로드 시 renderProjectList 호출하므로)
  await loadProjects();
  await loadFactories();

  // URL 파라미터에서 유형 확인 및 자동 선택
  const urlParams = new URLSearchParams(window.location.search);
  const preselectedType = urlParams.get('type');
  if (['nonconformity', 'safety', 'facility'].includes(preselectedType)) {
    onTypeSelect(preselectedType);
  }
});

/**
 * 이벤트 리스너 설정
 */
function setupEventListeners() {
  factorySelect.addEventListener('change', onFactoryChange);
  canvas.addEventListener('click', onMapClick);

  // 기타 위치 토글
  document.getElementById('useCustomLocation').addEventListener('change', (e) => {
    const customInput = document.getElementById('customLocationInput');
    customInput.classList.toggle('visible', e.target.checked);
    if (e.target.checked) {
      selectedWorkplaceId = null;
      selectedWorkplaceName = null;
      selectedTbmSessionId = null;
      selectedVisitRequestId = null;
      updateLocationInfo();
      renderProjectList(); // 기타 위치에서도 프로젝트 목록 표시
    }
  });

  // 유형 버튼 클릭
  document.querySelectorAll('.type-btn').forEach(btn => {
    btn.addEventListener('click', () => onTypeSelect(btn.dataset.type));
  });

  // 사진 슬롯 클릭
  document.querySelectorAll('.photo-slot').forEach(slot => {
    slot.addEventListener('click', (e) => {
      if (e.target.classList.contains('remove-btn')) return;
      currentPhotoIndex = parseInt(slot.dataset.index);
      photoInput.click();
    });
  });

  // 사진 삭제 버튼
  document.querySelectorAll('.photo-slot .remove-btn').forEach(btn => {
    btn.addEventListener('click', (e) => {
      e.stopPropagation();
      const slot = btn.closest('.photo-slot');
      const index = parseInt(slot.dataset.index);
      removePhoto(index);
    });
  });

  // 사진 선택
  photoInput.addEventListener('change', onPhotoSelect);
}

/**
 * 활성 프로젝트 목록 로드
 */
async function loadProjects() {
  try {
    const response = await fetch(`${API_BASE}/projects/active/list`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) throw new Error('프로젝트 목록 조회 실패');

    const data = await response.json();
    if (data.success && data.data) {
      allProjects = data.data;
    }
  } catch (error) {
    console.error('프로젝트 목록 로드 실패:', error);
    allProjects = [];
  }
}

/**
 * 공장 목록 로드
 */
async function loadFactories() {
  try {
    const response = await fetch(`${API_BASE}/workplaces/categories/active/list`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) throw new Error('공장 목록 조회 실패');

    const data = await response.json();
    if (data.success && data.data) {
      data.data.forEach(factory => {
        const option = document.createElement('option');
        option.value = factory.category_id;
        option.textContent = factory.category_name;
        factorySelect.appendChild(option);
      });

      if (data.data.length > 0) {
        factorySelect.value = data.data[0].category_id;
        onFactoryChange();
      }
    }
  } catch (error) {
    console.error('공장 목록 로드 실패:', error);
  }
}

/**
 * 공장 변경 시
 */
async function onFactoryChange() {
  selectedFactoryId = factorySelect.value;
  if (!selectedFactoryId) return;

  selectedWorkplaceId = null;
  selectedWorkplaceName = null;
  selectedTbmSessionId = null;
  selectedVisitRequestId = null;
  selectedProjectId = null;
  projectSelected = false;
  updateLocationInfo();

  await Promise.all([
    loadMapImage(),
    loadMapRegions(),
    loadTodayData()
  ]);

  renderMap();
  renderProjectList();
  updateStepStatus();
}

/**
 * 배치도 이미지 로드
 */
async function loadMapImage() {
  try {
    const response = await fetch(`${API_BASE}/workplaces/categories`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) return;

    const data = await response.json();
    if (data.success && data.data) {
      const selectedCategory = data.data.find(c => c.category_id == selectedFactoryId);
      if (selectedCategory && selectedCategory.layout_image) {
        const baseUrl = (window.API_BASE_URL || 'http://localhost:30105').replace('/api', '');
        const fullImageUrl = selectedCategory.layout_image.startsWith('http')
          ? selectedCategory.layout_image
          : `${baseUrl}${selectedCategory.layout_image}`;

        canvasImage = new Image();
        canvasImage.onload = () => renderMap();
        canvasImage.src = fullImageUrl;
      }
    }
  } catch (error) {
    console.error('배치도 이미지 로드 실패:', error);
  }
}

/**
 * 지도 영역 로드
 */
async function loadMapRegions() {
  try {
    const response = await fetch(`${API_BASE}/workplaces/categories/${selectedFactoryId}/map-regions`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) return;

    const data = await response.json();
    if (data.success) {
      mapRegions = data.data || [];
    }
  } catch (error) {
    console.error('지도 영역 로드 실패:', error);
  }
}

/**
 * 오늘 TBM/출입신청 데이터 로드
 */
async function loadTodayData() {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const today = `${year}-${month}-${day}`;

  try {
    const tbmResponse = await fetch(`${API_BASE}/tbm/sessions/date/${today}`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (tbmResponse.ok) {
      const tbmData = await tbmResponse.json();
      const sessions = tbmData.data || [];
      todayWorkers = sessions.map(session => {
        const memberCount = session.team_member_count || 0;
        return { ...session, member_count: memberCount };
      });
    }

    const visitResponse = await fetch(`${API_BASE}/workplace-visits/requests`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (visitResponse.ok) {
      const visitData = await visitResponse.json();
      todayVisitors = (visitData.data || []).filter(v => {
        const visitDateObj = new Date(v.visit_date);
        const visitYear = visitDateObj.getFullYear();
        const visitMonth = String(visitDateObj.getMonth() + 1).padStart(2, '0');
        const visitDay = String(visitDateObj.getDate()).padStart(2, '0');
        const visitDate = `${visitYear}-${visitMonth}-${visitDay}`;
        return visitDate === today &&
          (v.status === 'approved' || v.status === 'training_completed');
      });
    }
  } catch (error) {
    console.error('오늘 데이터 로드 실패:', error);
  }
}

/**
 * 둥근 모서리 사각형 그리기
 */
function drawRoundRect(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  ctx.lineTo(x + width - radius, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  ctx.lineTo(x + width, y + height - radius);
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
  ctx.lineTo(x + radius, y + height);
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
  ctx.lineTo(x, y + radius);
  ctx.quadraticCurveTo(x, y, x + radius, y);
  ctx.closePath();
}

/**
 * 지도 렌더링
 */
function renderMap() {
  if (!canvas || !ctx) return;

  const container = canvas.parentElement;
  const containerWidth = container.clientWidth - 2;
  const maxWidth = Math.min(containerWidth, 800);

  if (canvasImage && canvasImage.complete && canvasImage.naturalWidth > 0) {
    const imgWidth = canvasImage.naturalWidth;
    const imgHeight = canvasImage.naturalHeight;
    const scale = imgWidth > maxWidth ? maxWidth / imgWidth : 1;

    canvas.width = imgWidth * scale;
    canvas.height = imgHeight * scale;
    ctx.drawImage(canvasImage, 0, 0, canvas.width, canvas.height);
  } else {
    canvas.width = maxWidth;
    canvas.height = 300;
    ctx.fillStyle = '#f3f4f6';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#9ca3af';
    ctx.font = '14px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('배치도 이미지가 없습니다', canvas.width / 2, canvas.height / 2);
  }

  mapRegions.forEach(region => {
    const workers = todayWorkers.filter(w => w.workplace_id === region.workplace_id);
    const visitors = todayVisitors.filter(v => v.workplace_id === region.workplace_id);
    const workerCount = workers.reduce((sum, w) => sum + (w.member_count || 0), 0);
    const visitorCount = visitors.reduce((sum, v) => sum + (v.visitor_count || 0), 0);
    drawWorkplaceRegion(region, workerCount, visitorCount);
  });

  // 모바일일 때 전체화면 지도 버튼 표시
  const triggerBtn = document.getElementById('landscapeTriggerBtn');
  if (triggerBtn && window.innerWidth <= 768 && canvasImage && canvasImage.complete && mapRegions.length > 0) {
    triggerBtn.style.display = 'inline-flex';
  }
}

/**
 * 작업장 영역 그리기
 */
function drawWorkplaceRegion(region, workerCount, visitorCount) {
  const x1 = (region.x_start / 100) * canvas.width;
  const y1 = (region.y_start / 100) * canvas.height;
  const x2 = (region.x_end / 100) * canvas.width;
  const y2 = (region.y_end / 100) * canvas.height;
  const width = x2 - x1;
  const height = y2 - y1;
  const isSelected = region.workplace_id === selectedWorkplaceId;

  let fillColor, strokeColor, textColor;
  if (isSelected) {
    fillColor = 'rgba(34, 197, 94, 0.5)';
    strokeColor = 'rgb(22, 163, 74)';
    textColor = '#15803d';
  } else if (workerCount > 0 && visitorCount > 0) {
    fillColor = 'rgba(34, 197, 94, 0.4)';
    strokeColor = 'rgb(22, 163, 74)';
    textColor = '#166534';
  } else if (workerCount > 0) {
    fillColor = 'rgba(59, 130, 246, 0.4)';
    strokeColor = 'rgb(37, 99, 235)';
    textColor = '#1e40af';
  } else if (visitorCount > 0) {
    fillColor = 'rgba(168, 85, 247, 0.4)';
    strokeColor = 'rgb(147, 51, 234)';
    textColor = '#7c3aed';
  } else {
    fillColor = 'rgba(107, 114, 128, 0.35)';
    strokeColor = 'rgb(75, 85, 99)';
    textColor = '#374151';
  }

  ctx.fillStyle = fillColor;
  ctx.strokeStyle = strokeColor;
  ctx.lineWidth = isSelected ? 4 : 2.5;
  ctx.beginPath();
  ctx.rect(x1, y1, width, height);
  ctx.fill();
  ctx.stroke();

  const centerX = x1 + width / 2;
  const centerY = y1 + height / 2;

  ctx.font = 'bold 13px sans-serif';
  const textMetrics = ctx.measureText(region.workplace_name);
  const textWidth = textMetrics.width + 12;
  const textHeight = 20;

  ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
  drawRoundRect(ctx, centerX - textWidth / 2, centerY - textHeight / 2, textWidth, textHeight, 4);
  ctx.fill();

  ctx.fillStyle = textColor;
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(region.workplace_name, centerX, centerY);

  const total = workerCount + visitorCount;
  if (total > 0) {
    ctx.font = 'bold 12px sans-serif';
    const countText = `${total}명`;
    const countMetrics = ctx.measureText(countText);
    const countWidth = countMetrics.width + 10;
    const countHeight = 18;
    ctx.fillStyle = strokeColor;
    drawRoundRect(ctx, centerX - countWidth / 2, centerY + 12, countWidth, countHeight, 4);
    ctx.fill();
    ctx.fillStyle = '#ffffff';
    ctx.fillText(countText, centerX, centerY + 21);
  }
}

/**
 * 지도 클릭 처리
 */
function onMapClick(e) {
  const rect = canvas.getBoundingClientRect();
  const scaleX = canvas.width / rect.width;
  const scaleY = canvas.height / rect.height;
  const x = (e.clientX - rect.left) * scaleX;
  const y = (e.clientY - rect.top) * scaleY;

  for (const region of mapRegions) {
    const x1 = (region.x_start / 100) * canvas.width;
    const y1 = (region.y_start / 100) * canvas.height;
    const x2 = (region.x_end / 100) * canvas.width;
    const y2 = (region.y_end / 100) * canvas.height;

    if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
      selectWorkplace(region);
      return;
    }
  }
}

/**
 * 작업장 선택
 */
function selectWorkplace(region) {
  document.getElementById('useCustomLocation').checked = false;
  document.getElementById('customLocationInput').classList.remove('visible');

  selectedWorkplaceId = region.workplace_id;
  selectedWorkplaceName = region.workplace_name;
  selectedTbmSessionId = null;
  selectedVisitRequestId = null;
  selectedProjectId = null;
  projectSelected = false;

  updateLocationInfo();
  renderMap();
  renderProjectList();
  updateStepStatus();
}

// ==================== 가로모드 전체화면 지도 ====================

function openLandscapeMap() {
  if (!canvasImage || !canvasImage.complete || mapRegions.length === 0) return;

  const overlay = document.getElementById('landscapeOverlay');
  const inner = document.getElementById('landscapeInner');
  const lCanvas = document.getElementById('landscapeCanvas');
  if (!overlay || !lCanvas) return;

  overlay.style.display = 'flex';
  document.body.style.overflow = 'hidden';

  // 물리적 가로모드 여부
  const isPhysicalLandscape = window.innerWidth > window.innerHeight;
  inner.className = 'landscape-inner ' + (isPhysicalLandscape ? 'no-rotate' : 'rotated');

  // 가용 영역
  const headerH = 52;
  const pad = 16;
  let availW, availH;
  if (isPhysicalLandscape) {
    availW = window.innerWidth - pad * 2;
    availH = window.innerHeight - headerH - pad * 2;
  } else {
    availW = window.innerHeight - pad * 2;
    availH = window.innerWidth - headerH - pad * 2;
  }

  // 이미지 비율 유지
  const imgRatio = canvasImage.naturalWidth / canvasImage.naturalHeight;
  let cw, ch;
  if (availW / availH > imgRatio) {
    ch = availH;
    cw = ch * imgRatio;
  } else {
    cw = availW;
    ch = cw / imgRatio;
  }
  lCanvas.width = Math.round(cw);
  lCanvas.height = Math.round(ch);

  drawLandscapeMap();

  lCanvas.ontouchstart = handleLandscapeTouchStart;
  lCanvas.onclick = handleLandscapeClick;
}

function drawLandscapeMap() {
  const lCanvas = document.getElementById('landscapeCanvas');
  if (!lCanvas || !canvasImage) return;
  const lCtx = lCanvas.getContext('2d');

  lCtx.drawImage(canvasImage, 0, 0, lCanvas.width, lCanvas.height);

  mapRegions.forEach(region => {
    const workers = todayWorkers.filter(w => w.workplace_id === region.workplace_id);
    const visitors = todayVisitors.filter(v => v.workplace_id === region.workplace_id);
    const workerCount = workers.reduce((sum, w) => sum + (w.member_count || 0), 0);
    const visitorCount = visitors.reduce((sum, v) => sum + (v.visitor_count || 0), 0);

    const x1 = (region.x_start / 100) * lCanvas.width;
    const y1 = (region.y_start / 100) * lCanvas.height;
    const x2 = (region.x_end / 100) * lCanvas.width;
    const y2 = (region.y_end / 100) * lCanvas.height;
    const w = x2 - x1;
    const h = y2 - y1;
    const isSelected = region.workplace_id === selectedWorkplaceId;

    let fillColor, strokeColor, textColor;
    if (isSelected) {
      fillColor = 'rgba(34, 197, 94, 0.5)';
      strokeColor = 'rgb(22, 163, 74)';
      textColor = '#15803d';
    } else if (workerCount > 0 && visitorCount > 0) {
      fillColor = 'rgba(34, 197, 94, 0.4)';
      strokeColor = 'rgb(22, 163, 74)';
      textColor = '#166534';
    } else if (workerCount > 0) {
      fillColor = 'rgba(59, 130, 246, 0.4)';
      strokeColor = 'rgb(37, 99, 235)';
      textColor = '#1e40af';
    } else if (visitorCount > 0) {
      fillColor = 'rgba(168, 85, 247, 0.4)';
      strokeColor = 'rgb(147, 51, 234)';
      textColor = '#7c3aed';
    } else {
      fillColor = 'rgba(107, 114, 128, 0.35)';
      strokeColor = 'rgb(75, 85, 99)';
      textColor = '#374151';
    }

    lCtx.fillStyle = fillColor;
    lCtx.strokeStyle = strokeColor;
    lCtx.lineWidth = isSelected ? 4 : 2.5;
    lCtx.beginPath();
    lCtx.rect(x1, y1, w, h);
    lCtx.fill();
    lCtx.stroke();

    const centerX = x1 + w / 2;
    const centerY = y1 + h / 2;

    lCtx.font = 'bold 13px sans-serif';
    const textMetrics = lCtx.measureText(region.workplace_name);
    const textWidth = textMetrics.width + 12;
    const textHeight = 20;

    lCtx.fillStyle = 'rgba(255, 255, 255, 0.9)';
    drawRoundRect(lCtx, centerX - textWidth / 2, centerY - textHeight / 2, textWidth, textHeight, 4);
    lCtx.fill();

    lCtx.fillStyle = textColor;
    lCtx.textAlign = 'center';
    lCtx.textBaseline = 'middle';
    lCtx.fillText(region.workplace_name, centerX, centerY);

    const total = workerCount + visitorCount;
    if (total > 0) {
      lCtx.font = 'bold 12px sans-serif';
      const countText = `${total}명`;
      const countMetrics = lCtx.measureText(countText);
      const countWidth = countMetrics.width + 10;
      const countHeight = 18;
      lCtx.fillStyle = strokeColor;
      drawRoundRect(lCtx, centerX - countWidth / 2, centerY + 12, countWidth, countHeight, 4);
      lCtx.fill();
      lCtx.fillStyle = '#ffffff';
      lCtx.fillText(countText, centerX, centerY + 21);
    }
  });
}

function getLandscapeCoords(clientX, clientY) {
  const lCanvas = document.getElementById('landscapeCanvas');
  if (!lCanvas) return null;
  const rect = lCanvas.getBoundingClientRect();
  const inner = document.getElementById('landscapeInner');
  const isRotated = inner.classList.contains('rotated');

  if (!isRotated) {
    const scaleX = lCanvas.width / rect.width;
    const scaleY = lCanvas.height / rect.height;
    return {
      x: (clientX - rect.left) * scaleX,
      y: (clientY - rect.top) * scaleY
    };
  }

  const centerX = rect.left + rect.width / 2;
  const centerY = rect.top + rect.height / 2;
  const dx = clientX - centerX;
  const dy = clientY - centerY;
  const inverseDx = dy;
  const inverseDy = -dx;

  const unrotatedW = rect.height;
  const unrotatedH = rect.width;

  const canvasX = (inverseDx + unrotatedW / 2) / unrotatedW * lCanvas.width;
  const canvasY = (inverseDy + unrotatedH / 2) / unrotatedH * lCanvas.height;

  return { x: canvasX, y: canvasY };
}

function handleLandscapeTouchStart(e) {
  e.preventDefault();
  const touch = e.touches[0];
  const coords = getLandscapeCoords(touch.clientX, touch.clientY);
  if (coords) doLandscapeHitTest(coords.x, coords.y);
}

function handleLandscapeClick(e) {
  const coords = getLandscapeCoords(e.clientX, e.clientY);
  if (coords) doLandscapeHitTest(coords.x, coords.y);
}

function doLandscapeHitTest(cx, cy) {
  const lCanvas = document.getElementById('landscapeCanvas');
  if (!lCanvas) return;

  for (const region of mapRegions) {
    const x1 = (region.x_start / 100) * lCanvas.width;
    const y1 = (region.y_start / 100) * lCanvas.height;
    const x2 = (region.x_end / 100) * lCanvas.width;
    const y2 = (region.y_end / 100) * lCanvas.height;

    if (cx >= x1 && cx <= x2 && cy >= y1 && cy <= y2) {
      selectWorkplace(region);
      drawLandscapeMap();
      setTimeout(() => closeLandscapeMap(), 300);
      return;
    }
  }
}

function closeLandscapeMap() {
  const overlay = document.getElementById('landscapeOverlay');
  if (overlay) overlay.style.display = 'none';
  const lCanvas = document.getElementById('landscapeCanvas');
  if (lCanvas) {
    lCanvas.ontouchstart = null;
    lCanvas.onclick = null;
  }
  document.body.style.overflow = '';
}

/**
 * 프로젝트 목록 렌더링 (아코디언 방식)
 * 범주 1: 오늘 TBM 등록 작업 (해당 위치)
 * 범주 2: 활성 프로젝트 (DB)
 * 범주 3: 프로젝트 모름 (하단)
 */
function renderProjectList() {
  const list = document.getElementById('projectList');
  list.innerHTML = '';

  // 해당 위치의 TBM에서 프로젝트 정보 추출
  const workplaceWorkers = selectedWorkplaceId
    ? todayWorkers.filter(w => w.workplace_id === selectedWorkplaceId)
    : todayWorkers;
  const registeredProjectIds = new Set(
    workplaceWorkers.map(w => w.project_id).filter(Boolean)
  );

  // TBM 등록 프로젝트
  const tbmProjects = allProjects.filter(p => registeredProjectIds.has(p.project_id));
  // 나머지 활성 프로젝트
  const activeProjects = allProjects.filter(p => !registeredProjectIds.has(p.project_id));

  // ─── 범주 1: TBM 등록 작업 ───
  if (tbmProjects.length > 0) {
    const tbmGroup = createProjectGroup(
      '&#128736;&#65039;', '오늘 TBM 등록 작업', tbmProjects.length, 'tbm-group', true
    );
    const body = tbmGroup.querySelector('.project-group-body');
    tbmProjects.forEach(p => {
      const tbm = workplaceWorkers.find(w => w.project_id === p.project_id);
      const card = createProjectCard(p, tbm);
      body.appendChild(card);
    });
    list.appendChild(tbmGroup);
  }

  // ─── 범주 2: 활성 프로젝트 ───
  if (activeProjects.length > 0) {
    const activeGroup = createProjectGroup(
      '&#128196;', '활성 프로젝트', activeProjects.length, '', tbmProjects.length === 0
    );
    const body = activeGroup.querySelector('.project-group-body');
    activeProjects.forEach(p => {
      const card = createProjectCard(p, null);
      body.appendChild(card);
    });
    list.appendChild(activeGroup);
  }

  // 프로젝트가 아예 없을 때
  if (tbmProjects.length === 0 && activeProjects.length === 0) {
    const emptyMsg = document.createElement('div');
    emptyMsg.className = 'project-empty';
    emptyMsg.textContent = '등록된 프로젝트가 없습니다';
    list.appendChild(emptyMsg);
  }

  // ─── 범주 3: 프로젝트 모름 ───
  const unknownOption = document.createElement('div');
  unknownOption.className = 'project-skip';
  unknownOption.textContent = '프로젝트 여부 모름 (건너뛰기)';
  unknownOption.onclick = () => selectProject(null, null);
  list.appendChild(unknownOption);
}

/**
 * 아코디언 그룹 생성
 */
function createProjectGroup(icon, title, count, extraClass, openByDefault) {
  const group = document.createElement('div');
  group.className = 'project-group' + (extraClass ? ' ' + extraClass : '');
  if (openByDefault) group.classList.add('open');

  group.innerHTML = `
    <div class="project-group-header">
      <div class="group-left">
        <span class="group-icon">${icon}</span>
        <span class="group-title">${title}</span>
        <span class="group-count">${count}건</span>
      </div>
      <span class="group-arrow">&#9660;</span>
    </div>
    <div class="project-group-body"></div>
  `;

  const header = group.querySelector('.project-group-header');
  header.onclick = () => group.classList.toggle('open');

  return group;
}

/**
 * 프로젝트 카드 생성
 */
function createProjectCard(project, tbmSession) {
  const card = document.createElement('div');
  card.className = 'project-card';

  const safeName = escapeHtml(project.project_name || '');
  const safeJobNo = escapeHtml(project.job_no || '');
  const safePm = escapeHtml(project.pm || '');

  let html = `<div class="project-card-title">${safeName}</div>`;
  html += '<div class="project-card-desc">';
  if (safeJobNo) html += safeJobNo;
  if (safePm) html += ` &middot; PM: ${safePm}`;
  html += '</div>';

  if (tbmSession) {
    const safeTask = escapeHtml(tbmSession.task_name || '');
    const count = parseInt(tbmSession.member_count) || 0;
    html += `<div class="tbm-info">TBM: ${safeTask} (${count}명)</div>`;
  }

  card.innerHTML = html;
  card._projectId = project.project_id;
  card.onclick = (e) => {
    e.stopPropagation();
    selectProject(project.project_id, tbmSession);
  };

  return card;
}

/**
 * 프로젝트 선택 처리
 */
function selectProject(projectId, tbmSession) {
  selectedProjectId = projectId;
  projectSelected = true;

  if (tbmSession) {
    selectedTbmSessionId = tbmSession.session_id;
  } else {
    selectedTbmSessionId = null;
  }
  selectedVisitRequestId = null;

  // 모든 선택 해제 → 현재 선택 표시
  const list = document.getElementById('projectList');
  list.querySelectorAll('.project-card, .project-skip').forEach(el => el.classList.remove('selected'));

  if (projectId === null) {
    // 프로젝트 모름
    list.querySelector('.project-skip').classList.add('selected');
  } else {
    // 카드에서 해당 프로젝트 찾아 선택
    list.querySelectorAll('.project-card').forEach(card => {
      if (card._projectId === projectId) card.classList.add('selected');
    });
  }

  updateLocationInfo();
  updateStepStatus();
}

/**
 * 선택된 위치 정보 업데이트
 */
function updateLocationInfo() {
  const infoBox = document.getElementById('selectedLocationInfo');
  const customLocation = document.getElementById('customLocation').value;
  const useCustom = document.getElementById('useCustomLocation').checked;

  if (useCustom && customLocation) {
    infoBox.classList.remove('empty');
    infoBox.innerHTML = `<strong>선택된 위치:</strong> ${escapeHtml(customLocation)}`;
  } else if (selectedWorkplaceName) {
    infoBox.classList.remove('empty');
    let html = `<strong>선택된 위치:</strong> ${escapeHtml(selectedWorkplaceName)}`;

    if (selectedProjectId) {
      const proj = allProjects.find(p => p.project_id === selectedProjectId);
      if (proj) {
        html += `<br><span style="color:#059669;">프로젝트: ${escapeHtml(proj.project_name)}</span>`;
      }
    }

    if (selectedTbmSessionId) {
      const worker = todayWorkers.find(w => w.session_id === selectedTbmSessionId);
      if (worker) {
        html += `<br><span style="color:#2563eb;">TBM: ${escapeHtml(worker.task_name || '-')}</span>`;
      }
    }

    infoBox.innerHTML = html;
  } else {
    infoBox.classList.add('empty');
    infoBox.textContent = '지도에서 작업장을 클릭하여 위치를 선택하세요';
  }
}

/**
 * 유형 선택
 */
function onTypeSelect(type) {
  selectedType = type;
  selectedCategoryId = null;
  selectedCategoryName = null;
  selectedItemId = null;
  customItemName = null;

  document.querySelectorAll('.type-btn').forEach(btn => {
    btn.classList.toggle('selected', btn.dataset.type === type);
  });

  loadCategories(type);
  updateStepStatus();
}

/**
 * 카테고리 로드
 */
async function loadCategories(type) {
  try {
    const response = await fetch(`${API_BASE}/work-issues/categories/type/${type}`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) throw new Error('카테고리 조회 실패');

    const data = await response.json();
    if (data.success && data.data) {
      renderCategories(data.data);
    }
  } catch (error) {
    console.error('카테고리 로드 실패:', error);
  }
}

/**
 * 카테고리 렌더링
 */
function renderCategories(categories) {
  const container = document.getElementById('categoryContainer');
  const grid = document.getElementById('categoryGrid');
  grid.innerHTML = '';

  categories.forEach(cat => {
    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'category-btn';
    btn.textContent = cat.category_name;
    btn.onclick = () => onCategorySelect(cat);
    grid.appendChild(btn);
  });

  container.style.display = 'block';
}

/**
 * 카테고리 선택
 */
function onCategorySelect(category) {
  selectedCategoryId = category.category_id;
  selectedCategoryName = category.category_name;
  selectedItemId = null;
  customItemName = null;

  document.querySelectorAll('.category-btn').forEach(btn => {
    btn.classList.toggle('selected', btn.textContent === category.category_name);
  });

  loadItems(category.category_id);
  updateStepStatus();
}

/**
 * 항목 로드
 */
async function loadItems(categoryId) {
  try {
    const response = await fetch(`${API_BASE}/work-issues/items/category/${categoryId}`, {
      headers: { 'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}` }
    });

    if (!response.ok) throw new Error('항목 조회 실패');

    const data = await response.json();
    if (data.success && data.data) {
      renderItems(data.data);
    }
  } catch (error) {
    console.error('항목 로드 실패:', error);
  }
}

/**
 * 항목 렌더링
 */
function renderItems(items) {
  const grid = document.getElementById('itemGrid');
  grid.innerHTML = '';

  items.forEach(item => {
    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'item-btn';
    btn.textContent = item.item_name;
    btn.dataset.severity = item.severity;
    btn.onclick = () => onItemSelect(item, btn);
    grid.appendChild(btn);
  });

  const customBtn = document.createElement('button');
  customBtn.type = 'button';
  customBtn.className = 'item-btn custom-input-btn';
  customBtn.textContent = '+ 직접 입력';
  customBtn.onclick = () => showCustomItemInput();
  grid.appendChild(customBtn);

  document.getElementById('customItemInput').style.display = 'none';
  document.getElementById('customItemName').value = '';
  customItemName = null;
}

/**
 * 항목 선택
 */
function onItemSelect(item, btn) {
  document.querySelectorAll('.item-btn').forEach(b => b.classList.remove('selected'));
  btn.classList.add('selected');
  selectedItemId = item.item_id;
  customItemName = null;
  document.getElementById('customItemInput').style.display = 'none';
  updateStepStatus();
}

/**
 * 직접 입력 영역 표시
 */
function showCustomItemInput() {
  document.querySelectorAll('.item-btn').forEach(b => b.classList.remove('selected'));
  document.querySelector('.custom-input-btn').classList.add('selected');
  selectedItemId = null;
  document.getElementById('customItemInput').style.display = 'flex';
  document.getElementById('customItemName').focus();
}

/**
 * 직접 입력 확인
 */
function confirmCustomItem() {
  const input = document.getElementById('customItemName');
  const value = input.value.trim();
  if (!value) {
    alert('항목명을 입력해주세요.');
    input.focus();
    return;
  }
  customItemName = value;
  selectedItemId = null;
  const customBtn = document.querySelector('.custom-input-btn');
  customBtn.textContent = `\u2713 ${value}`;
  customBtn.classList.add('selected');
  updateStepStatus();
}

/**
 * 직접 입력 취소
 */
function cancelCustomItem() {
  document.getElementById('customItemInput').style.display = 'none';
  document.getElementById('customItemName').value = '';
  customItemName = null;
  const customBtn = document.querySelector('.custom-input-btn');
  customBtn.textContent = '+ 직접 입력';
  customBtn.classList.remove('selected');
  updateStepStatus();
}

/**
 * 사진 선택 (클라이언트에서 리사이징 후 저장)
 */
function onPhotoSelect(e) {
  const file = e.target.files[0];
  if (!file) return;

  resizeImage(file, 1280, 0.8).then(dataUrl => {
    photos[currentPhotoIndex] = dataUrl;
    updatePhotoSlot(currentPhotoIndex);
    updateStepStatus();
  }).catch(() => {
    // 리사이징 실패 시 원본 사용
    const reader = new FileReader();
    reader.onload = (event) => {
      photos[currentPhotoIndex] = event.target.result;
      updatePhotoSlot(currentPhotoIndex);
      updateStepStatus();
    };
    reader.readAsDataURL(file);
  });
  e.target.value = '';
}

/**
 * 이미지 리사이징 (Canvas 이용)
 * @param {File} file - 원본 파일
 * @param {number} maxSize - 최대 가로/세로 픽셀
 * @param {number} quality - JPEG 품질 (0~1)
 * @returns {Promise<string>} base64 data URL
 */
function resizeImage(file, maxSize, quality) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      let w = img.width, h = img.height;
      if (w > maxSize || h > maxSize) {
        if (w > h) { h = Math.round(h * maxSize / w); w = maxSize; }
        else { w = Math.round(w * maxSize / h); h = maxSize; }
      }
      const cvs = document.createElement('canvas');
      cvs.width = w;
      cvs.height = h;
      cvs.getContext('2d').drawImage(img, 0, 0, w, h);
      resolve(cvs.toDataURL('image/jpeg', quality));
    };
    img.onerror = reject;
    img.src = URL.createObjectURL(file);
  });
}

/**
 * 사진 슬롯 업데이트
 */
function updatePhotoSlot(index) {
  const slot = document.querySelector(`.photo-slot[data-index="${index}"]`);

  if (photos[index]) {
    slot.classList.add('has-photo');
    let img = slot.querySelector('img');
    if (!img) {
      img = document.createElement('img');
      slot.insertBefore(img, slot.firstChild);
    }
    img.src = photos[index];
  } else {
    slot.classList.remove('has-photo');
    const img = slot.querySelector('img');
    if (img) img.remove();
  }
}

/**
 * 사진 삭제
 */
function removePhoto(index) {
  photos[index] = null;
  updatePhotoSlot(index);
  updateStepStatus();
}

/**
 * 단계 상태 업데이트
 * 5단계: 유형(1) → 위치(2) → 프로젝트(3) → 항목(4) → 사진(5)
 */
function updateStepStatus() {
  const steps = document.querySelectorAll('.step');
  const customLocation = document.getElementById('customLocation').value;
  const useCustom = document.getElementById('useCustomLocation').checked;

  const step1Complete = !!selectedType;
  const step2Complete = (useCustom && customLocation) || !!selectedWorkplaceId;
  const step3Complete = projectSelected;
  const step4Complete = !!selectedCategoryId && (!!selectedItemId || !!customItemName);
  const hasPhoto = photos.some(p => p !== null);

  // Reset all
  steps.forEach(s => { s.classList.remove('active', 'completed'); });

  if (step1Complete) { steps[0].classList.add('completed'); } else { steps[0].classList.add('active'); }
  if (step1Complete && step2Complete) { steps[1].classList.add('completed'); } else if (step1Complete) { steps[1].classList.add('active'); }
  if (step1Complete && step2Complete && step3Complete) { steps[2].classList.add('completed'); } else if (step1Complete && step2Complete) { steps[2].classList.add('active'); }
  if (step4Complete) { steps[3].classList.add('completed'); } else if (step1Complete && step2Complete && step3Complete) { steps[3].classList.add('active'); }
  if (hasPhoto) { steps[4].classList.add('completed'); } else if (step4Complete) { steps[4].classList.add('active'); }

  const submitBtn = document.getElementById('submitBtn');
  submitBtn.disabled = !(step1Complete && step2Complete && step3Complete && step4Complete && hasPhoto);
}

/**
 * 신고 제출
 */
async function submitReport() {
  const submitBtn = document.getElementById('submitBtn');
  submitBtn.disabled = true;
  submitBtn.textContent = '제출 중...';

  try {
    const useCustom = document.getElementById('useCustomLocation').checked;
    const customLocation = document.getElementById('customLocation').value;
    const additionalDescription = document.getElementById('additionalDescription').value;

    const requestBody = {
      factory_category_id: useCustom ? null : selectedFactoryId,
      workplace_id: useCustom ? null : selectedWorkplaceId,
      custom_location: useCustom ? customLocation : null,
      project_id: selectedProjectId,
      tbm_session_id: selectedTbmSessionId,
      visit_request_id: selectedVisitRequestId,
      issue_category_id: selectedCategoryId,
      issue_item_id: selectedItemId,
      custom_item_name: customItemName,
      additional_description: additionalDescription || null,
      photos: photos.filter(p => p !== null)
    };

    const response = await fetch(`${API_BASE}/work-issues`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${(window.getSSOToken ? window.getSSOToken() : localStorage.getItem('sso_token'))}`
      },
      body: JSON.stringify(requestBody)
    });

    const data = await response.json();

    if (data.success) {
      document.getElementById('successModal').style.display = 'flex';
    } else {
      throw new Error(data.error || '신고 등록 실패');
    }
  } catch (error) {
    console.error('신고 제출 실패:', error);
    alert('신고 등록에 실패했습니다: ' + error.message);
  } finally {
    submitBtn.disabled = false;
    submitBtn.textContent = '신고 제출';
  }
}

// 기타 위치 입력 시 위치 정보 업데이트
document.addEventListener('DOMContentLoaded', () => {
  const customLocationInput = document.getElementById('customLocation');
  if (customLocationInput) {
    customLocationInput.addEventListener('input', () => {
      updateLocationInfo();
      updateStepStatus();
    });
  }
});

// 전역 함수 노출
window.submitReport = submitReport;
window.showCustomItemInput = showCustomItemInput;
window.confirmCustomItem = confirmCustomItem;
window.cancelCustomItem = cancelCustomItem;
