/**
 * TBM Mobile - Main UI Logic
 * tbm-mobile.html에서 추출된 인라인 JS (로직 변경 없음)
 */
(function() {
  'use strict';

  var currentTab = 'today';
  var allSessions = [];
  var todaySessions = [];
  var currentUser = null;
  var loadedDays = 7;
  var esc = window.escapeHtml || function(s) { return s || ''; };
  var todayAssignments = []; // 당일 배정 현황

  // 세부 편집 상태
  var deSessionId = null;
  var deSession = null;
  var deMembers = [];
  var deTasks = [];
  var deWpCats = [];
  var deWpMap = {};     // category_id -> [workplaces]
  var deSelected = {};  // index -> boolean (그룹 선택용)

  // 피커 상태
  var pickerMode = '';           // 'task' | 'workplace'
  var pickerWpStep = 'category'; // 'category' | 'place'
  var pickerSelectedCatId = null;

  // busy guard - 비동기 함수 중복 호출 방지
  var _busy = {};
  function isBusy(key) { return !!_busy[key]; }
  function setBusy(key) { _busy[key] = true; }
  function clearBusy(key) { delete _busy[key]; }

  function showLoading(msg) {
    var el = document.getElementById('loadingOverlay');
    if (el) {
      document.getElementById('loadingText').textContent = msg || '불러오는 중...';
      el.classList.add('active');
    }
  }
  function hideLoading() {
    var el = document.getElementById('loadingOverlay');
    if (el) el.classList.remove('active');
  }

  // 초기화
  document.addEventListener('DOMContentLoaded', async function() {
    var now = new Date();
    var days = ['일','월','화','수','목','금','토'];
    var dateEl = document.getElementById('headerDate');
    if (dateEl) {
      dateEl.textContent = now.getFullYear() + '.' +
        String(now.getMonth()+1).padStart(2,'0') + '.' +
        String(now.getDate()).padStart(2,'0') + ' (' + days[now.getDay()] + ')';
    }

    try {
      await window.waitForApi(8000);
    } catch(e) {
      document.getElementById('tbmContent').innerHTML =
        '<div class="m-empty"><div class="m-empty-icon">&#9888;</div><div class="m-empty-text">서버 연결에 실패했습니다</div><div class="m-empty-sub">페이지를 새로고침해 주세요</div></div>';
      return;
    }

    currentUser = JSON.parse(localStorage.getItem('sso_user') || '{}');
    await loadData();
  });

  function getTodayStr() {
    var now = new Date();
    return now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
  }

  async function loadData() {
    try {
      var today = new Date();
      var todayStr = getTodayStr();
      var dates = [];
      for (var i = 0; i < loadedDays; i++) {
        var d = new Date(today);
        d.setDate(d.getDate() - i);
        dates.push(d.getFullYear() + '-' + String(d.getMonth()+1).padStart(2,'0') + '-' + String(d.getDate()).padStart(2,'0'));
      }

      var API = window.TbmAPI;
      var promises = dates.map(function(date) {
        return API.fetchSessionsByDate(date);
      });
      var results = await Promise.all(promises);

      allSessions = [];
      results.forEach(function(sessions) {
        if (sessions && sessions.length > 0) {
          allSessions = allSessions.concat(sessions);
        }
      });

      // 당일 세션 = 오늘 날짜만
      todaySessions = allSessions.filter(function(s) {
        var sDate = s.session_date ? s.session_date.split('T')[0] : '';
        return sDate === todayStr;
      });

      document.getElementById('todayCount').textContent = todaySessions.length;
      document.getElementById('allCount').textContent = allSessions.length;

      renderList();
    } catch (error) {
      console.error('TBM 로드 오류:', error);
      document.getElementById('tbmContent').innerHTML =
        '<div class="m-empty"><div class="m-empty-text">데이터를 불러올 수 없습니다</div></div>';
    }
  }

  window.switchTab = function(tab) {
    currentTab = tab;
    document.querySelectorAll('.m-tab').forEach(function(el) {
      el.classList.toggle('active', el.dataset.tab === tab);
    });
    renderList();
  };

  function isMySession(s) {
    var userId = currentUser.user_id;
    var workerId = currentUser.user_id;
    var userName = currentUser.name;
    return (userId && String(s.created_by) === String(userId)) ||
           (workerId && String(s.leader_user_id) === String(workerId)) ||
           (userName && s.created_by_name === userName);
  }

  function renderList() {
    var sessions = currentTab === 'today' ? todaySessions : allSessions;
    var content = document.getElementById('tbmContent');

    if (sessions.length === 0) {
      var emptyMsg = currentTab === 'today' ?
        '오늘 등록된 TBM이 없습니다' : '등록된 TBM이 없습니다';
      content.innerHTML =
        '<div class="m-empty">' +
          '<div class="m-empty-icon">&#128221;</div>' +
          '<div class="m-empty-text">' + emptyMsg + '</div>' +
          (currentTab === 'all' ? '<div class="m-empty-sub">최근 ' + loadedDays + '일 기준</div>' : '') +
        '</div>';
      return;
    }

    var grouped = {};
    sessions.forEach(function(s) {
      var date = s.session_date ? s.session_date.split('T')[0] : '';
      if (/^\d{4}-\d{2}-\d{2}$/.test(date)) { /* ok */ }
      else if (s.session_date) { date = new Date(s.session_date).toISOString().split('T')[0]; }
      if (!grouped[date]) grouped[date] = [];
      grouped[date].push(s);
    });

    var sortedDates = Object.keys(grouped).sort().reverse();
    var todayStr = getTodayStr();
    var yesterday = new Date(Date.now() - 86400000).toISOString().split('T')[0];

    var html = '';
    sortedDates.forEach(function(date) {
      var label = date;
      if (date === todayStr) label = '오늘';
      else if (date === yesterday) label = '어제';
      else {
        var parts = date.split('-');
        var dayNames = ['일','월','화','수','목','금','토'];
        var dObj = new Date(date + 'T00:00:00');
        label = parseInt(parts[1]) + '/' + parseInt(parts[2]) + ' (' + dayNames[dObj.getDay()] + ')';
      }

      html += '<div class="m-date-group"><span class="m-date-label">' + label + '</span></div>';

      grouped[date].forEach(function(s) {
        var sid = s.session_id;
        var status = s.status || 'draft';
        var leaderName = s.leader_name || s.created_by_name || '미지정';
        var memberCount = (parseInt(s.team_member_count) || 0);
        var memberNames = s.team_member_names || '';
        var subText = memberNames || '팀원 없음';
        var isMine = isMySession(s);
        var transferCount = parseInt(s.transfer_count) || 0;

        var createdTime = '';
        if (s.created_at) {
          try {
            var t = new Date(s.created_at);
            createdTime = String(t.getHours()).padStart(2,'0') + ':' + String(t.getMinutes()).padStart(2,'0');
          } catch(e) {}
        }

        var statusLabel = status === 'completed' ? '완료' : (status === 'cancelled' ? '취소' : '진행');

        var badge = '';
        if (status === 'draft') {
          if (!s.task_id) {
            badge = '<span class="m-detail-badge incomplete">세부 미입력</span>';
          } else {
            badge = '<span class="m-detail-badge complete">입력 완료</span>';
          }
        }

        // 이동 뱃지
        var transferBadge = '';
        if (transferCount > 0) {
          transferBadge = '<span class="m-transfer-badge">' + transferCount + '건 이동</span>';
        }

        // 당일 탭에서 다른 반장의 draft TBM 클릭 → 빼오기 시트
        var clickAction;
        if (isMine && status === 'draft') {
          clickAction = 'openDetailEditSheet(' + sid + ')';
        } else if (!isMine && status === 'draft' && currentTab === 'today') {
          clickAction = 'openPullSheet(' + sid + ')';
        } else if (status !== 'draft') {
          clickAction = 'toggleDetail(' + sid + ')';
        } else {
          clickAction = 'toggleDetail(' + sid + ')';
        }

        var myTbmClass = isMine ? ' my-tbm' : '';
        var leaderDisplay = esc(leaderName);
        if (!isMine && currentTab === 'today') {
          leaderDisplay += '<span class="m-leader-badge">타 반장</span>';
        }

        html += '<div class="m-tbm-row' + myTbmClass + '" data-sid="' + sid + '" onclick="' + clickAction + '">' +
          '<div class="m-row-status ' + status + '" title="' + statusLabel + '"></div>' +
          '<div class="m-row-body">' +
            '<div class="m-row-main">' + leaderDisplay + badge + transferBadge + '</div>' +
            '<div class="m-row-sub">' + esc(subText) + '</div>' +
          '</div>' +
          '<div class="m-row-right">' +
            '<div class="m-row-count">' + memberCount + '<span class="m-row-count-label">명</span></div>' +
            (createdTime ? '<div class="m-row-time">' + createdTime + '</div>' : '') +
          '</div>' +
        '</div>';

        if (status !== 'draft') {
          var taskName = s.task_name || '';
          var workplaceName = s.work_location || '';
          html += '<div class="m-tbm-detail" id="detail_' + sid + '">' +
            '<div class="m-detail-row"><span class="m-detail-label">상태</span><span class="m-detail-value">' + statusLabel + '</span></div>' +
            '<div class="m-detail-row"><span class="m-detail-label">입력자</span><span class="m-detail-value">' + esc(leaderName) + '</span></div>' +
            (taskName ? '<div class="m-detail-row"><span class="m-detail-label">작업</span><span class="m-detail-value">' + esc(taskName) + '</span></div>' : '') +
            (workplaceName ? '<div class="m-detail-row"><span class="m-detail-label">장소</span><span class="m-detail-value">' + esc(workplaceName) + '</span></div>' : '') +
            '<div class="m-detail-row"><span class="m-detail-label">인원</span><span class="m-detail-value">' + esc(memberNames || '없음') + ' (' + memberCount + '명)</span></div>' +
            '<div class="m-detail-actions">' +
              '<button type="button" class="m-detail-btn" onclick="event.stopPropagation(); openDetailEditSheet(' + sid + ');">상세보기</button>' +
            '</div>' +
          '</div>';
        }
      });
    });

    if (currentTab === 'all') {
      html += '<button type="button" class="m-load-more" onclick="loadMore()">이전 기록 더 보기</button>';
    }
    content.innerHTML = html;
  }

  window.toggleDetail = function(sid) {
    var row = document.querySelector('.m-tbm-row[data-sid="' + sid + '"]');
    if (!row) return;
    document.querySelectorAll('.m-tbm-row.expanded').forEach(function(el) {
      if (el !== row) el.classList.remove('expanded');
    });
    row.classList.toggle('expanded');
  };

  window.loadMore = function() {
    loadedDays += 7;
    loadData();
  };

  // ─── 세부 편집 바텀시트 ───

  window.openDetailEditSheet = async function(sid) {
    if (isBusy('detailEdit')) return;
    setBusy('detailEdit');
    showLoading('불러오는 중...');
    deSessionId = sid;
    deSelected = {};
    try {
      var API = window.TbmAPI;
      var results = await Promise.all([
        API.getSession(sid).catch(function() { return null; }),
        API.getTeamMembers(sid).catch(function() { return []; }),
        API.loadTasks().catch(function() { return []; }),
        API.loadWorkplaceCategories().catch(function() { return []; }),
        API.loadActiveWorkplacesList().catch(function() { return []; })
      ]);

      deSession = results[0];
      deMembers = results[1];
      deTasks = results[2] || window.TbmState.allTasks || [];
      deWpCats = results[3] || window.TbmState.allWorkplaceCategories || [];
      var allWorkplaces = results[4];

      if (!deSession) { window.showToast('TBM 정보를 불러올 수 없습니다.', 'error'); return; }
      if (deMembers.length === 0) { window.showToast('팀원이 없습니다.', 'error'); return; }

      // work_type 필터
      var workTypeId = deSession.work_type_id || (deMembers[0] && deMembers[0].work_type_id);
      if (workTypeId) {
        deTasks = deTasks.filter(function(t) { return t.work_type_id == workTypeId; });
      }

      // 작업장소 맵 (category_id 기준)
      deWpMap = {};
      allWorkplaces.forEach(function(wp) {
        var catId = wp.category_id || 0;
        if (!deWpMap[catId]) deWpMap[catId] = [];
        deWpMap[catId].push(wp);
      });

      renderDetailEditSheet();
      document.getElementById('deSelectAll').checked = false;
      updateGroupBar();
      document.getElementById('detailEditOverlay').style.display = 'block';
      document.getElementById('detailEditSheet').style.display = 'block';
    } catch(e) {
      console.error('세부 편집 로드 오류:', e);
      window.showToast('데이터를 불러오는 중 오류가 발생했습니다.', 'error');
    } finally {
      hideLoading();
      clearBusy('detailEdit');
    }
  };

  function renderDetailEditSheet() {
    var html = '';
    deMembers.forEach(function(m, i) {
      var hasBoth = m.task_id && m.workplace_id;
      var cardClass = hasBoth ? 'filled' : 'unfilled';
      var statusHtml = hasBoth
        ? '<span class="de-worker-status ok">입력완료</span>'
        : '<span class="de-worker-status missing">미입력</span>';

      // work_hours 표시
      var workHoursTag = '';
      if (m.work_hours !== null && m.work_hours !== undefined) {
        workHoursTag = '<span class="m-work-hours-tag">' + parseFloat(m.work_hours) + 'h</span>';
      }
      // 분할 항목이면 프로젝트명 표시
      var projectTag = '';
      if (m.split_seq > 0 && m.project_name) {
        projectTag = '<span style="font-size:0.625rem; background:#dbeafe; color:#1e40af; padding:0.0625rem 0.375rem; border-radius:0.25rem; margin-left:0.25rem;">' + esc(m.project_name) + '</span>';
      } else if (m.project_name && m.project_id !== deSession.project_id) {
        projectTag = '<span style="font-size:0.625rem; background:#fef3c7; color:#92400e; padding:0.0625rem 0.375rem; border-radius:0.25rem; margin-left:0.25rem;">' + esc(m.project_name) + '</span>';
      }

      var taskOptions = '<option value="">작업 선택...</option>';
      deTasks.forEach(function(t) {
        var sel = (m.task_id && m.task_id == t.task_id) ? ' selected' : '';
        taskOptions += '<option value="' + t.task_id + '"' + sel + '>' + esc(t.task_name) + '</option>';
      });

      var currentCatId = m.workplace_category_id || '';
      var catOptions = '<option value="">분류...</option>';
      deWpCats.forEach(function(c) {
        var sel = (currentCatId && currentCatId == c.category_id) ? ' selected' : '';
        catOptions += '<option value="' + c.category_id + '"' + sel + '>' + esc(c.category_name) + '</option>';
      });

      var wpOptions = '<option value="">장소...</option>';
      if (currentCatId && deWpMap[currentCatId]) {
        deWpMap[currentCatId].forEach(function(wp) {
          var sel = (m.workplace_id && m.workplace_id == wp.workplace_id) ? ' selected' : '';
          wpOptions += '<option value="' + wp.workplace_id + '"' + sel + '>' + esc(wp.workplace_name) + '</option>';
        });
      }

      html += '<div class="de-worker-card ' + cardClass + '" id="de_card_' + i + '">' +
        '<div style="display:flex; align-items:center;">' +
          '<input type="checkbox" class="de-worker-check" id="de_check_' + i + '" onchange="onWorkerCheck(' + i + ')">' +
          '<span class="de-worker-name">' + esc(m.worker_name) + '</span> ' +
          '<span class="de-worker-job">' + esc(m.job_type || '') + '</span>' +
          workHoursTag +
          projectTag +
          statusHtml +
          '<button type="button" class="de-split-btn" onclick="event.stopPropagation(); openSplitSheet(' + i + ')">분할</button>' +
        '</div>' +
        '<div class="de-worker-fields">' +
          '<div class="de-field-row">' +
            '<span class="de-field-label">작업</span>' +
            '<select id="de_task_' + i + '" onchange="updateCardStatus(' + i + ')">' + taskOptions + '</select>' +
          '</div>' +
          '<div class="de-field-row">' +
            '<span class="de-field-label">장소</span>' +
            '<select id="de_wpcat_' + i + '" onchange="onDeWpCatChange(' + i + ')">' + catOptions + '</select>' +
            '<select id="de_wp_' + i + '" onchange="updateCardStatus(' + i + ')">' + wpOptions + '</select>' +
          '</div>' +
        '</div>' +
      '</div>';
    });
    document.getElementById('deWorkerList').innerHTML = html;
  }

  window.updateCardStatus = function(idx) {
    var card = document.getElementById('de_card_' + idx);
    var taskVal = document.getElementById('de_task_' + idx).value;
    var wpVal = document.getElementById('de_wp_' + idx).value;
    var statusEl = card.querySelector('.de-worker-status');
    if (taskVal && wpVal) {
      card.className = 'de-worker-card filled';
      statusEl.className = 'de-worker-status ok';
      statusEl.textContent = '입력완료';
    } else {
      card.className = 'de-worker-card unfilled';
      statusEl.className = 'de-worker-status missing';
      statusEl.textContent = '미입력';
    }
  };

  window.onDeWpCatChange = function(idx) {
    var catId = document.getElementById('de_wpcat_' + idx).value;
    var wpSel = document.getElementById('de_wp_' + idx);
    wpSel.innerHTML = '<option value="">장소...</option>';
    if (catId && deWpMap[catId]) {
      deWpMap[catId].forEach(function(wp) {
        wpSel.innerHTML += '<option value="' + wp.workplace_id + '">' + esc(wp.workplace_name) + '</option>';
      });
    }
    updateCardStatus(idx);
  };

  // ─── 그룹 선택 ───

  window.onWorkerCheck = function(idx) {
    deSelected[idx] = document.getElementById('de_check_' + idx).checked;
    var allChecked = true;
    for (var i = 0; i < deMembers.length; i++) {
      if (!deSelected[i]) { allChecked = false; break; }
    }
    document.getElementById('deSelectAll').checked = allChecked;
    updateGroupBar();
  };

  window.toggleSelectAll = function() {
    var checked = document.getElementById('deSelectAll').checked;
    for (var i = 0; i < deMembers.length; i++) {
      deSelected[i] = checked;
      document.getElementById('de_check_' + i).checked = checked;
    }
    updateGroupBar();
  };

  function getSelectedIndices() {
    var arr = [];
    for (var i = 0; i < deMembers.length; i++) {
      if (deSelected[i]) arr.push(i);
    }
    return arr;
  }

  function updateGroupBar() {
    var indices = getSelectedIndices();
    var bar = document.getElementById('deGroupBar');
    var countEl = document.getElementById('deSelectedCount');
    var labelEl = document.getElementById('deGroupLabel');
    if (indices.length > 0) {
      bar.className = 'de-group-bar visible';
      labelEl.textContent = indices.length + '명 선택';
      countEl.textContent = indices.length + '명';
    } else {
      bar.className = 'de-group-bar';
      countEl.textContent = '';
    }
  }

  // ─── 피커 (작업/장소 선택 팝업) ───

  window.openPicker = function(mode) {
    var indices = getSelectedIndices();
    if (indices.length === 0) {
      window.showToast('작업자를 먼저 선택하세요.', 'error');
      return;
    }
    pickerMode = mode;
    pickerWpStep = 'category';
    pickerSelectedCatId = null;

    if (mode === 'task') {
      renderTaskPicker();
    } else {
      renderWorkplaceCatPicker();
    }
    document.getElementById('pickerOverlay').style.display = 'block';
    document.getElementById('pickerSheet').style.display = 'block';
  };

  window.closePicker = function() {
    document.getElementById('pickerOverlay').style.display = 'none';
    document.getElementById('pickerSheet').style.display = 'none';
  };

  function renderTaskPicker() {
    document.getElementById('pickerTitle').textContent = '작업 선택';
    var listEl = document.getElementById('pickerList');
    var html = '';
    deTasks.forEach(function(t) {
      html += '<div class="picker-item" onclick="pickTask(' + t.task_id + ')">' +
        esc(t.task_name) +
      '</div>';
    });
    if (deTasks.length === 0) {
      html = '<div style="padding:1.5rem; text-align:center; color:#9ca3af;">등록된 작업이 없습니다</div>';
    }
    listEl.innerHTML = html;
    // 새 작업 추가 영역
    var addRow = document.getElementById('pickerAddRow');
    addRow.style.display = 'flex';
    document.getElementById('pickerAddInput').placeholder = '새 작업명 입력...';
    document.getElementById('pickerAddInput').value = '';
    document.getElementById('pickerAddBtn').onclick = function() { addNewTask(); };
  }

  function renderWorkplaceCatPicker() {
    pickerWpStep = 'category';
    document.getElementById('pickerTitle').textContent = '장소 분류 선택';
    var listEl = document.getElementById('pickerList');
    var html = '';
    deWpCats.forEach(function(c) {
      var count = deWpMap[c.category_id] ? deWpMap[c.category_id].length : 0;
      html += '<div class="picker-item" onclick="pickWpCategory(' + c.category_id + ')">' +
        esc(c.category_name) +
        '<span class="picker-item-sub">' + count + '개 장소</span>' +
      '</div>';
    });
    if (deWpCats.length === 0) {
      html = '<div style="padding:1.5rem; text-align:center; color:#9ca3af;">등록된 분류가 없습니다</div>';
    }
    listEl.innerHTML = html;
    document.getElementById('pickerAddRow').style.display = 'none';
  }

  function renderWorkplacePicker(catId) {
    pickerWpStep = 'place';
    pickerSelectedCatId = catId;
    var catName = '';
    deWpCats.forEach(function(c) { if (c.category_id == catId) catName = c.category_name; });
    document.getElementById('pickerTitle').textContent = esc(catName) + ' - 장소 선택';
    var listEl = document.getElementById('pickerList');
    var workplaces = deWpMap[catId] || [];
    var html = '<div class="picker-item" style="color:#6b7280;" onclick="renderWorkplaceCatPicker()">&#8592; 분류 다시 선택</div>';
    workplaces.forEach(function(wp) {
      html += '<div class="picker-item" onclick="pickWorkplace(' + catId + ',' + wp.workplace_id + ')">' +
        esc(wp.workplace_name) +
      '</div>';
    });
    if (workplaces.length === 0) {
      html += '<div style="padding:1rem; text-align:center; color:#9ca3af;">등록된 장소가 없습니다</div>';
    }
    listEl.innerHTML = html;
    document.getElementById('pickerAddRow').style.display = 'none';
  }

  window.pickTask = function(taskId) {
    var indices = getSelectedIndices();
    indices.forEach(function(i) {
      document.getElementById('de_task_' + i).value = taskId;
      updateCardStatus(i);
    });
    closePicker();
    window.showToast(indices.length + '명에게 작업 적용', 'success');
  };

  window.pickWpCategory = function(catId) {
    renderWorkplacePicker(catId);
  };

  window.pickWorkplace = function(catId, wpId) {
    var indices = getSelectedIndices();
    indices.forEach(function(i) {
      // 분류 설정
      document.getElementById('de_wpcat_' + i).value = catId;
      // 장소 옵션 갱신
      var wpSel = document.getElementById('de_wp_' + i);
      wpSel.innerHTML = '<option value="">장소...</option>';
      if (deWpMap[catId]) {
        deWpMap[catId].forEach(function(wp) {
          wpSel.innerHTML += '<option value="' + wp.workplace_id + '">' + esc(wp.workplace_name) + '</option>';
        });
      }
      wpSel.value = wpId;
      updateCardStatus(i);
    });
    closePicker();
    window.showToast(indices.length + '명에게 장소 적용', 'success');
  };

  // ─── 새 작업/공정 추가 ───

  async function addNewTask() {
    var name = document.getElementById('pickerAddInput').value.trim();
    if (!name) { window.showToast('작업명을 입력하세요.', 'error'); return; }

    var workTypeId = deSession.work_type_id || (deMembers[0] && deMembers[0].work_type_id) || null;
    try {
      var res = await window.TbmAPI.createTask({
        task_name: name,
        work_type_id: workTypeId
      });
      if (res && res.success) {
        var newId = res.data.task_id;
        // deTasks에 추가
        deTasks.push({ task_id: newId, task_name: name, work_type_id: workTypeId });
        // 모든 작업자 드롭다운 갱신
        for (var i = 0; i < deMembers.length; i++) {
          var sel = document.getElementById('de_task_' + i);
          var opt = document.createElement('option');
          opt.value = newId;
          opt.textContent = name;
          sel.appendChild(opt);
        }
        // 피커 다시 렌더링
        renderTaskPicker();
        window.showToast('작업 "' + name + '" 추가됨', 'success');
      } else {
        window.showToast('작업 추가 실패', 'error');
      }
    } catch(e) {
      console.error(e);
      window.showToast('오류가 발생했습니다.', 'error');
    }
  }

  window.closeDetailEditSheet = function() {
    document.getElementById('detailEditOverlay').style.display = 'none';
    document.getElementById('detailEditSheet').style.display = 'none';
    clearBusy('detailEdit');
  };

  // 저장 (부분 입력도 허용)
  window.saveDetailEdit = async function() {
    var members = [];
    for (var i = 0; i < deMembers.length; i++) {
      var m = deMembers[i];
      var taskId = document.getElementById('de_task_' + i).value || null;
      var wpCatId = document.getElementById('de_wpcat_' + i).value || null;
      var wpId = document.getElementById('de_wp_' + i).value || null;

      members.push({
        user_id: m.user_id,
        project_id: m.project_id || deSession.project_id || null,
        work_type_id: m.work_type_id || deSession.work_type_id || null,
        task_id: taskId ? parseInt(taskId) : null,
        workplace_category_id: wpCatId ? parseInt(wpCatId) : null,
        workplace_id: wpId ? parseInt(wpId) : null,
        work_detail: m.work_detail || null
      });
    }

    var btn = document.getElementById('deSaveBtn');
    btn.disabled = true;
    btn.textContent = '저장 중...';

    try {
      await window.TbmAPI.clearTeamMembers(deSessionId);
      var res = await window.TbmAPI.addTeamMembers(deSessionId, members);
      if (res && res.success) {
        closeDetailEditSheet();
        window.showToast('세부 내역이 저장되었습니다.', 'success');
        await loadData();
      } else {
        window.showToast('저장에 실패했습니다.', 'error');
      }
    } catch(e) {
      console.error('세부 편집 저장 오류:', e);
      window.showToast('오류가 발생했습니다.', 'error');
    } finally {
      btn.disabled = false;
      btn.textContent = '저장';
    }
  };

  // 완료 (미입력 있으면 차단)
  window.completeFromDetailSheet = function() {
    var incomplete = [];
    for (var i = 0; i < deMembers.length; i++) {
      var taskVal = document.getElementById('de_task_' + i).value;
      var wpVal = document.getElementById('de_wp_' + i).value;
      if (!taskVal || !wpVal) {
        incomplete.push(deMembers[i].worker_name);
      }
    }
    if (incomplete.length > 0) {
      window.showToast('미입력: ' + incomplete.join(', '), 'error');
      return;
    }
    var sid = deSessionId;
    saveDetailEdit().then(function() {
      window.completeTbm(sid);
    });
  };

  window.deleteFromDetailSheet = function() {
    var sid = deSessionId;
    closeDetailEditSheet();
    window.deleteTbm(sid);
  };

  // ─── TBM 완료 바텀시트 ───

  var completeSessionId = null;
  var completeTeamMembers = [];

  window.completeTbm = async function(sid) {
    if (isBusy('complete')) return;
    setBusy('complete');
    showLoading('확인 중...');
    completeSessionId = sid;
    try {
      completeTeamMembers = await window.TbmAPI.getTeamMembers(sid).catch(function() { return []; });
      if (completeTeamMembers.length === 0) {
        window.showToast('팀원이 없습니다.', 'error');
        return;
      }

      // 세부 미입력 작업자 체크
      var incomplete = completeTeamMembers.filter(function(m) { return !m.task_id || !m.workplace_id; });
      if (incomplete.length > 0) {
        var names = incomplete.map(function(m) { return m.worker_name; }).join(', ');
        window.showToast('세부 미입력: ' + names + ' - 세부 내역을 먼저 입력하세요.', 'error');
        return;
      }

      renderCompleteSheet();
      document.getElementById('completeOverlay').style.display = 'block';
      document.getElementById('completeSheet').style.display = 'block';
    } catch(e) {
      console.error(e);
      window.showToast('팀원 조회 중 오류가 발생했습니다.', 'error');
    } finally {
      hideLoading();
      clearBusy('complete');
    }
  };

  function renderCompleteSheet() {
    var html = '';
    completeTeamMembers.forEach(function(m, i) {
      html += '<div style="padding:0.625rem 0; border-bottom:1px solid #f3f4f6;">' +
        '<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.375rem;">' +
          '<div><strong style="font-size:0.875rem;">' + esc(m.worker_name) + '</strong> <span style="font-size:0.75rem; color:#6b7280;">(' + esc(m.job_type || '') + ')</span></div>' +
        '</div>' +
        '<div style="display:flex; gap:0.375rem; align-items:center; flex-wrap:wrap;">' +
          '<select id="att_type_' + i + '" onchange="onAttTypeChange(' + i + ')" style="flex:1; min-width:120px; padding:0.5rem; border:1px solid #d1d5db; border-radius:0.375rem; font-size:0.8125rem; background:white;">' +
            '<option value="regular">정시근로 (8h)</option>' +
            '<option value="overtime">연장근무 (8h+)</option>' +
            '<option value="annual">연차 (휴무)</option>' +
            '<option value="half">반차 (4h)</option>' +
            '<option value="quarter">반반차 (6h)</option>' +
            '<option value="early">조퇴</option>' +
          '</select>' +
          '<input type="number" id="att_hours_' + i + '" placeholder="추가시간" step="0.5" min="0" max="8" style="display:none; width:70px; padding:0.5rem; border:1px solid #d1d5db; border-radius:0.375rem; font-size:0.8125rem; text-align:center;">' +
          '<span id="att_hint_' + i + '" style="font-size:0.75rem; color:#6b7280;"></span>' +
        '</div>' +
      '</div>';
    });
    document.getElementById('completeWorkerList').innerHTML = html;
  }

  window.onAttTypeChange = function(idx) {
    var sel = document.getElementById('att_type_' + idx);
    var inp = document.getElementById('att_hours_' + idx);
    var hint = document.getElementById('att_hint_' + idx);
    var val = sel.value;
    if (val === 'overtime') {
      inp.style.display = 'block'; inp.placeholder = '+시간'; inp.value = ''; hint.textContent = '';
    } else if (val === 'early') {
      inp.style.display = 'block'; inp.placeholder = '근무시간'; inp.value = ''; hint.textContent = '';
    } else {
      inp.style.display = 'none'; inp.value = '';
      var labels = { regular:'8h', annual:'연차 자동처리', half:'4h', quarter:'6h' };
      hint.textContent = labels[val] || '';
    }
  };

  window.closeCompleteSheet = function() {
    document.getElementById('completeOverlay').style.display = 'none';
    document.getElementById('completeSheet').style.display = 'none';
  };

  window.submitCompleteSheet = async function() {
    var attendanceData = [];
    for (var i = 0; i < completeTeamMembers.length; i++) {
      var type = document.getElementById('att_type_' + i).value;
      var hoursVal = document.getElementById('att_hours_' + i).value;
      var hours = hoursVal ? parseFloat(hoursVal) : null;
      if (type === 'overtime' && (!hours || hours <= 0)) {
        window.showToast(esc(completeTeamMembers[i].worker_name) + '의 추가 시간을 입력해주세요.', 'error'); return;
      }
      if (type === 'early' && (!hours || hours <= 0)) {
        window.showToast(esc(completeTeamMembers[i].worker_name) + '의 근무 시간을 입력해주세요.', 'error'); return;
      }
      attendanceData.push({ user_id: completeTeamMembers[i].user_id, attendance_type: type, attendance_hours: hours });
    }

    var btn = document.getElementById('completeSheetBtn');
    btn.disabled = true; btn.textContent = '처리 중...';

    try {
      var now = new Date();
      var endTime = String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0');
      var res = await window.apiCall('/tbm/sessions/' + completeSessionId + '/complete', 'POST', {
        end_time: endTime, attendance_data: attendanceData
      });
      if (res && res.success) {
        closeCompleteSheet();
        window.showToast('TBM이 완료 처리되었습니다.', 'success');
        await loadData();
      } else {
        window.showToast('완료 처리에 실패했습니다.', 'error');
      }
    } catch(e) {
      console.error(e);
      window.showToast('오류가 발생했습니다.', 'error');
    } finally {
      btn.disabled = false; btn.textContent = '완료 처리';
    }
  };

  window.deleteTbm = async function(sid) {
    if (!confirm('이 TBM을 삭제하시겠습니까?')) return;
    try {
      var res = await window.TbmAPI.deleteSession(sid);
      if (res && res.success) {
        window.showToast('TBM이 삭제되었습니다.', 'success');
        await loadData();
      } else {
        window.showToast('삭제에 실패했습니다.', 'error');
      }
    } catch(e) {
      window.showToast('오류가 발생했습니다.', 'error');
    }
  };

  // ─── 분할 기능 ───

  var splitMemberIdx = null;
  var splitOption = 'keep'; // 'keep' | 'send'
  var splitTargetSessionId = null;
  var cachedProjects = null;
  var cachedWorkTypes = null;

  // 프로젝트/공정 목록 로딩 (캐시)
  async function loadProjectsAndWorkTypes() {
    if (!cachedProjects) {
      try {
        cachedProjects = await window.TbmAPI.loadProjects() || [];
      } catch(e) { cachedProjects = []; }
    }
    if (!cachedWorkTypes) {
      try {
        cachedWorkTypes = await window.TbmAPI.loadWorkTypes() || [];
      } catch(e) { cachedWorkTypes = []; }
    }
  }

  function populateProjectSelect(selectId, currentProjectId) {
    var sel = document.getElementById(selectId);
    var html = '<option value="">원래 프로젝트 유지</option>';
    (cachedProjects || []).forEach(function(p) {
      html += '<option value="' + p.project_id + '"' + (p.project_id == currentProjectId ? ' selected' : '') + '>' + esc(p.project_name) + '</option>';
    });
    sel.innerHTML = html;
  }

  function populateWorkTypeSelect(selectId, currentWorkTypeId) {
    var sel = document.getElementById(selectId);
    var html = '<option value="">원래 공정 유지</option>';
    (cachedWorkTypes || []).forEach(function(wt) {
      html += '<option value="' + wt.id + '"' + (wt.id == currentWorkTypeId ? ' selected' : '') + '>' + esc(wt.name) + '</option>';
    });
    sel.innerHTML = html;
  }

  window.openSplitSheet = async function(memberIdx) {
    if (isBusy('split')) return;
    setBusy('split');
    showLoading('불러오는 중...');
    splitMemberIdx = memberIdx;
    splitOption = 'keep';
    splitTargetSessionId = null;
    var m = deMembers[memberIdx];
    var currentHours = m.work_hours === null || m.work_hours === undefined ? 8 : parseFloat(m.work_hours);

    document.getElementById('splitTitle').textContent = esc(m.worker_name) + ' 작업 분할';
    document.getElementById('splitSubtitle').textContent = '현재 ' + currentHours + 'h 배정';
    document.getElementById('splitHours').value = '';
    document.getElementById('splitHours').max = currentHours - 0.5;
    document.getElementById('splitRemainder').textContent = '';
    document.getElementById('splitOptKeep').className = 'split-radio-item active';
    document.getElementById('splitOptSend').className = 'split-radio-item';
    document.getElementById('splitSessionPicker').style.display = 'none';

    // 시간 입력 시 나머지 자동 계산
    document.getElementById('splitHours').oninput = function() {
      var val = parseFloat(this.value);
      if (val && val > 0 && val < currentHours) {
        document.getElementById('splitRemainder').textContent = '나머지: ' + (currentHours - val) + 'h';
      } else {
        document.getElementById('splitRemainder').textContent = '';
      }
    };

    // 프로젝트/공정 목록 로드 + 드롭다운 채우기
    await loadProjectsAndWorkTypes();
    populateProjectSelect('splitProjectId', null);
    populateWorkTypeSelect('splitWorkTypeId', null);

    // 다른 세션 목록 로드 (당일)
    loadSplitSessionList();

    document.getElementById('splitOverlay').style.display = 'block';
    document.getElementById('splitSheet').style.display = 'block';
    hideLoading();
    clearBusy('split');
  };

  async function loadSplitSessionList() {
    var todayStr = getTodayStr();
    try {
      var sessions = await window.TbmAPI.fetchSessionsByDate(todayStr);
      if (sessions && sessions.length > 0) {
        var html = '';
        sessions.forEach(function(s) {
          if (s.session_id === deSessionId) return; // 현재 세션 제외
          if (s.status !== 'draft') return; // draft만
          var leaderName = s.leader_name || s.created_by_name || '미지정';
          var workType = s.work_type_name || '';
          html += '<div class="split-session-item" data-sid="' + s.session_id + '" onclick="selectSplitSession(' + s.session_id + ')">' +
            esc(leaderName) + (workType ? ' - ' + esc(workType) : '') +
            ' <span style="font-size:0.6875rem; color:#9ca3af;">(' + (parseInt(s.team_member_count)||0) + '명)</span>' +
          '</div>';
        });
        if (!html) html = '<div style="padding:0.75rem; font-size:0.8125rem; color:#9ca3af; text-align:center;">다른 TBM이 없습니다</div>';
        document.getElementById('splitSessionList').innerHTML = html;
      }
    } catch(e) {
      console.error(e);
    }
  }

  window.setSplitOption = function(opt) {
    splitOption = opt;
    splitTargetSessionId = null;
    document.getElementById('splitOptKeep').className = 'split-radio-item' + (opt === 'keep' ? ' active' : '');
    document.getElementById('splitOptSend').className = 'split-radio-item' + (opt === 'send' ? ' active' : '');
    document.getElementById('splitSessionPicker').style.display = opt === 'send' ? 'block' : 'none';
    // 세션 선택 초기화
    document.querySelectorAll('.split-session-item').forEach(function(el) { el.classList.remove('active'); });
  };

  window.selectSplitSession = function(sid) {
    splitTargetSessionId = sid;
    document.querySelectorAll('.split-session-item').forEach(function(el) {
      el.classList.toggle('active', parseInt(el.dataset.sid) === sid);
    });
  };

  window.closeSplitSheet = function() {
    document.getElementById('splitOverlay').style.display = 'none';
    document.getElementById('splitSheet').style.display = 'none';
    clearBusy('split');
  };

  window.saveSplit = async function() {
    var m = deMembers[splitMemberIdx];
    var currentHours = m.work_hours === null || m.work_hours === undefined ? 8 : parseFloat(m.work_hours);
    var splitHours = parseFloat(document.getElementById('splitHours').value);

    if (!splitHours || splitHours <= 0 || splitHours >= currentHours) {
      window.showToast('올바른 시간을 입력하세요 (0 < 시간 < ' + currentHours + ')', 'error');
      return;
    }

    var btn = document.getElementById('splitSaveBtn');
    btn.disabled = true;
    btn.textContent = '처리 중...';

    try {
      // 프로젝트/공정 선택값
      var selProjectId = document.getElementById('splitProjectId').value;
      var selWorkTypeId = document.getElementById('splitWorkTypeId').value;

      if (splitOption === 'keep') {
        var remainHoursKeep = currentHours - splitHours;
        var newProjectId = selProjectId ? parseInt(selProjectId) : (m.project_id || null);
        var newWorkTypeId = selWorkTypeId ? parseInt(selWorkTypeId) : (m.work_type_id || null);

        // 1) 기존 항목: 시간만 줄이기 (프로젝트/공정 유지)
        await window.TbmAPI.updateTeamMember(deSessionId, {
          user_id: m.user_id,
          project_id: m.project_id || null,
          work_type_id: m.work_type_id || null,
          task_id: m.task_id || null,
          workplace_category_id: m.workplace_category_id || null,
          workplace_id: m.workplace_id || null,
          work_detail: m.work_detail || null,
          is_present: true,
          work_hours: splitHours
        });

        // 2) 나머지 시간으로 새 항목 추가 (프로젝트/공정 변경 가능)
        await window.TbmAPI.splitAssignment(deSessionId, {
          user_id: m.user_id,
          work_hours: remainHoursKeep,
          project_id: newProjectId,
          work_type_id: newWorkTypeId
        });

        closeSplitSheet();
        // 세부 편집 데이터 다시 로드
        deMembers = await window.TbmAPI.getTeamMembers(deSessionId).catch(function() { return deMembers; });
        renderDetailEditSheet();
        window.showToast('분할 완료: ' + splitHours + 'h + ' + remainHoursKeep + 'h', 'success');
      } else if (splitOption === 'send') {
        if (!splitTargetSessionId) {
          window.showToast('이동할 TBM을 선택하세요.', 'error');
          btn.disabled = false;
          btn.textContent = '분할 저장';
          return;
        }
        var remainHours = currentHours - splitHours;
        var destProjectId = selProjectId ? parseInt(selProjectId) : (m.project_id || null);
        var destWorkTypeId = selWorkTypeId ? parseInt(selWorkTypeId) : (m.work_type_id || null);
        // transfer API 호출
        var res = await window.TbmAPI.transfer({
          transfer_type: 'send',
          user_id: m.user_id,
          source_session_id: deSessionId,
          dest_session_id: splitTargetSessionId,
          hours: remainHours,
          project_id: destProjectId,
          work_type_id: destWorkTypeId
        });

        if (res && res.success) {
          closeSplitSheet();
          closeDetailEditSheet();
          window.showToast('이동 완료' + (res.data && res.data.warning ? ' (' + res.data.warning + ')' : ''), 'success');
          await loadData();
        } else {
          window.showToast(res?.message || '이동 실패', 'error');
        }
      }
    } catch(e) {
      console.error('분할 오류:', e);
      window.showToast('오류가 발생했습니다.', 'error');
    } finally {
      btn.disabled = false;
      btn.textContent = '분할 저장';
    }
  };

  // ─── 빼오기 기능 ───

  var pullSessionId = null;
  var pullMembers = [];
  var pullWorker = null; // 빼오기 대상
  var myDraftSession = null; // 내 draft TBM

  window.openPullSheet = async function(sid) {
    if (isBusy('pull')) return;
    setBusy('pull');
    showLoading('불러오는 중...');
    pullSessionId = sid;
    try {
      pullMembers = await window.TbmAPI.getTeamMembers(sid).catch(function() { return []; });

      var session = await window.TbmAPI.getSession(sid).catch(function() { return null; });
      var leaderName = session ? (session.leader_name || session.created_by_name || '미지정') : '미지정';

      document.getElementById('pullTitle').textContent = esc(leaderName) + ' 반장 팀';
      document.getElementById('pullSubtitle').textContent = pullMembers.length + '명 배정';

      // 내 draft TBM 확인
      myDraftSession = todaySessions.find(function(s) {
        return isMySession(s) && s.status === 'draft';
      });

      var html = '';
      pullMembers.forEach(function(m) {
        var hours = m.work_hours === null || m.work_hours === undefined ? 8 : parseFloat(m.work_hours);
        var hoursText = hours + 'h';

        var btnHtml = '';
        if (!myDraftSession) {
          btnHtml = '<button type="button" class="pull-btn" disabled title="내 TBM이 없음">내 TBM 없음</button>';
        } else {
          btnHtml = '<button type="button" class="pull-btn" onclick="event.stopPropagation(); startPull(' + m.user_id + ', \'' + esc(m.worker_name).replace(/'/g, "\\'") + '\', ' + hours + ')">빼오기</button>';
        }

        html += '<div class="pull-member-item">' +
          '<div class="pull-member-info">' +
            '<div class="pull-member-name">' + esc(m.worker_name) + ' <span class="m-work-hours-tag">' + hoursText + '</span></div>' +
            '<div class="pull-member-sub">' + esc(m.job_type || '') + '</div>' +
          '</div>' +
          btnHtml +
        '</div>';
      });

      if (pullMembers.length === 0) {
        html = '<div style="padding:1.5rem; text-align:center; color:#9ca3af;">팀원이 없습니다</div>';
      }

      document.getElementById('pullMemberList').innerHTML = html;
      document.getElementById('pullOverlay').style.display = 'block';
      document.getElementById('pullSheet').style.display = 'block';
    } catch(e) {
      console.error('빼오기 로드 오류:', e);
      window.showToast('데이터를 불러올 수 없습니다.', 'error');
    } finally {
      hideLoading();
      clearBusy('pull');
    }
  };

  window.closePullSheet = function() {
    document.getElementById('pullOverlay').style.display = 'none';
    document.getElementById('pullSheet').style.display = 'none';
    clearBusy('pull');
  };

  window.startPull = async function(workerId, workerName, maxHours) {
    pullWorker = { user_id: workerId, worker_name: workerName, max_hours: maxHours };
    document.getElementById('pullHoursTitle').textContent = esc(workerName) + ' 빼오기';
    document.getElementById('pullHoursSubtitle').textContent = '최대 ' + maxHours + 'h 가능';
    document.getElementById('pullHoursInput').value = maxHours;
    document.getElementById('pullHoursInput').max = maxHours;

    // 프로젝트/공정 드롭다운 채우기
    await loadProjectsAndWorkTypes();
    var myProject = myDraftSession ? myDraftSession.project_id : null;
    var myWorkType = myDraftSession ? myDraftSession.work_type_id : null;
    populateProjectSelect('pullProjectId', myProject);
    populateWorkTypeSelect('pullWorkTypeId', myWorkType);

    document.getElementById('pullHoursOverlay').style.display = 'block';
    document.getElementById('pullHoursSheet').style.display = 'block';
  };

  window.closePullHoursModal = function() {
    document.getElementById('pullHoursOverlay').style.display = 'none';
    document.getElementById('pullHoursSheet').style.display = 'none';
  };

  window.confirmPull = async function() {
    var hours = parseFloat(document.getElementById('pullHoursInput').value);
    if (!hours || hours <= 0 || hours > pullWorker.max_hours) {
      window.showToast('올바른 시간을 입력하세요 (0 < 시간 <= ' + pullWorker.max_hours + ')', 'error');
      return;
    }

    var btn = document.getElementById('pullHoursSaveBtn');
    btn.disabled = true;
    btn.textContent = '처리 중...';

    try {
      var pullProjectId = document.getElementById('pullProjectId').value || null;
      var pullWorkTypeId = document.getElementById('pullWorkTypeId').value || null;
      var res = await window.TbmAPI.transfer({
        transfer_type: 'pull',
        user_id: pullWorker.user_id,
        source_session_id: pullSessionId,
        dest_session_id: myDraftSession.session_id,
        hours: hours,
        project_id: pullProjectId ? parseInt(pullProjectId) : null,
        work_type_id: pullWorkTypeId ? parseInt(pullWorkTypeId) : null
      });

      if (res && res.success) {
        closePullHoursModal();
        closePullSheet();
        window.showToast(esc(pullWorker.worker_name) + ' ' + hours + 'h 빼오기 완료' +
          (res.data && res.data.warning ? ' (' + res.data.warning + ')' : ''), 'success');
        await loadData();
      } else {
        window.showToast(res?.message || '빼오기 실패', 'error');
      }
    } catch(e) {
      console.error('빼오기 오류:', e);
      window.showToast('오류가 발생했습니다.', 'error');
    } finally {
      btn.disabled = false;
      btn.textContent = '빼오기 실행';
    }
  };

  // ─── 인계 바텀시트 ───

  var handoverSessionId = null;
  var handoverSession = null;

  window.handoverFromDetailSheet = function() {
    var sid = deSessionId;
    closeDetailEditSheet();
    openHandoverSheet(sid);
  };

  async function openHandoverSheet(sid) {
    if (isBusy('handover')) return;
    setBusy('handover');
    showLoading('인계 정보 불러오는 중...');
    handoverSessionId = sid;

    try {
      var API = window.TbmAPI;
      var results = await Promise.all([
        API.getSession(sid).catch(function() { return null; }),
        API.getTeamMembers(sid).catch(function() { return []; }),
        API.loadWorkers().catch(function() { return []; })
      ]);

      handoverSession = results[0];
      var team = results[1];
      var workers = results[2];

      if (!handoverSession) {
        window.showToast('세션 정보를 불러올 수 없습니다.', 'error');
        return;
      }

      // 현재 세션 리더를 제외한 반장/그룹장 목록
      var leaders = workers.filter(function(w) {
        return (w.job_type === 'leader' || w.job_type === '그룹장' || w.job_type === 'admin') &&
               w.user_id !== handoverSession.leader_user_id;
      });

      var leaderSelect = document.getElementById('handoverLeaderId');
      leaderSelect.innerHTML = '<option value="">반장 선택...</option>' +
        leaders.map(function(w) {
          return '<option value="' + w.user_id + '">' + esc(w.worker_name) + ' (' + (w.job_type || '') + ')</option>';
        }).join('');

      // 인계할 팀원 체크리스트
      var listEl = document.getElementById('handoverWorkerList');
      if (team.length === 0) {
        listEl.innerHTML = '<p style="padding:1rem; color:#6b7280; text-align:center;">팀원이 없습니다.</p>';
      } else {
        listEl.innerHTML = team.map(function(m) {
          return '<label style="display:flex; align-items:center; gap:0.5rem; padding:0.5rem; cursor:pointer;">' +
            '<input type="checkbox" class="handover-worker-cb" value="' + m.user_id + '" checked style="width:16px; height:16px;">' +
            '<span style="font-weight:500; font-size:0.875rem;">' + esc(m.worker_name) + '</span>' +
            '<span style="font-size:0.75rem; color:#6b7280; margin-left:auto;">' + (m.job_type || '') + '</span>' +
            '</label>';
        }).join('');
      }

      document.getElementById('handoverNotes').value = '';

      document.getElementById('handoverOverlay').style.display = 'block';
      document.getElementById('handoverSheet').style.display = 'block';
    } catch(e) {
      console.error('인계 시트 열기 오류:', e);
      window.showToast('인계 정보를 불러오는 중 오류가 발생했습니다.', 'error');
    } finally {
      hideLoading();
      clearBusy('handover');
    }
  }
  window.openHandoverSheet = openHandoverSheet;

  window.closeHandoverSheet = function() {
    document.getElementById('handoverOverlay').style.display = 'none';
    document.getElementById('handoverSheet').style.display = 'none';
  };

  window.submitHandover = async function() {
    var toLeaderId = parseInt(document.getElementById('handoverLeaderId').value);
    var notes = document.getElementById('handoverNotes').value;

    if (!toLeaderId) {
      window.showToast('인계 대상 반장을 선택해주세요.', 'error');
      return;
    }

    var workerIds = [];
    document.querySelectorAll('.handover-worker-cb:checked').forEach(function(cb) {
      workerIds.push(parseInt(cb.value));
    });

    if (workerIds.length === 0) {
      window.showToast('인계할 팀원을 최소 1명 선택해주세요.', 'error');
      return;
    }

    var btn = document.querySelector('#handoverSheet .split-btn');
    btn.disabled = true;
    btn.textContent = '처리 중...';

    try {
      var today = getTodayStr();
      var now = new Date().toTimeString().slice(0, 5);

      var handoverData = {
        session_id: handoverSessionId,
        from_leader_user_id: handoverSession.leader_user_id,
        to_leader_user_id: toLeaderId,
        handover_date: today,
        handover_time: now,
        reason: '모바일 인계',
        handover_notes: notes,
        user_ids: workerIds
      };

      var res = await window.TbmAPI.saveHandover(handoverData);
      if (res && res.success) {
        window.closeHandoverSheet();
        window.showToast('작업 인계가 요청되었습니다.', 'success');
        await loadData();
      } else {
        window.showToast(res?.message || '인계 요청에 실패했습니다.', 'error');
      }
    } catch(e) {
      console.error('인계 저장 오류:', e);
      window.showToast('인계 중 오류가 발생했습니다.', 'error');
    } finally {
      btn.disabled = false;
      btn.textContent = '인계 요청';
    }
  };
})();
