// controllers/tbmController.js - TBM 시스템 컨트롤러
const TbmModel = require('../models/tbmModel');
const TbmTransferModel = require('../models/tbmTransferModel');
const logger = require('../utils/logger');

const TbmController = {
  // ==================== TBM 세션 관련 ====================

  createSession: async (req, res) => {
    try {
      const sessionData = {
        session_date: req.body.session_date,
        leader_user_id: req.body.leader_user_id || null,
        project_id: req.body.project_id || null,
        work_location: req.body.work_location || null,
        work_description: req.body.work_description || null,
        safety_notes: req.body.safety_notes || null,
        start_time: req.body.start_time || null,
        created_by: req.user.user_id
      };

      if (!sessionData.session_date) {
        return res.status(400).json({ success: false, message: 'TBM 날짜는 필수입니다.' });
      }

      const result = await TbmModel.createSession(sessionData);
      res.status(201).json({
        success: true,
        message: 'TBM 세션이 생성되었습니다.',
        data: { session_id: result.insertId, ...sessionData }
      });
    } catch (err) {
      logger.error('TBM 세션 생성 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 생성 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getSessionsByDate: async (req, res) => {
    try {
      const { date } = req.params;
      if (!date) {
        return res.status(400).json({ success: false, message: '날짜 정보가 필요합니다.' });
      }

      const results = await TbmModel.getSessionsByDate(date);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('TBM 세션 조회 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getSessionById: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const results = await TbmModel.getSessionById(sessionId);

      if (results.length === 0) {
        return res.status(404).json({ success: false, message: 'TBM 세션을 찾을 수 없습니다.' });
      }

      res.json({ success: true, data: results[0] });
    } catch (err) {
      logger.error('TBM 세션 상세 조회 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 상세 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  updateSession: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const sessionData = {
        project_id: req.body.project_id,
        work_location: req.body.work_location,
        work_description: req.body.work_description,
        safety_notes: req.body.safety_notes,
        status: req.body.status || 'draft'
      };

      const result = await TbmModel.updateSession(sessionId, sessionData);
      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: 'TBM 세션을 찾을 수 없습니다.' });
      }

      res.json({ success: true, message: 'TBM 세션이 수정되었습니다.' });
    } catch (err) {
      logger.error('TBM 세션 수정 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 수정 중 오류가 발생했습니다.', error: err.message });
    }
  },

  completeSession: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const endTime = req.body.end_time || new Date().toTimeString().slice(0, 8);
      const attendanceData = req.body.attendance_data;

      let result;
      if (attendanceData && Array.isArray(attendanceData) && attendanceData.length > 0) {
        result = await TbmModel.completeSessionWithAttendance(sessionId, endTime, attendanceData, req.user.user_id);
      } else {
        result = await TbmModel.completeSession(sessionId, endTime);
      }

      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: 'TBM 세션을 찾을 수 없습니다.' });
      }

      res.json({ success: true, message: 'TBM 세션이 완료되었습니다.' });
    } catch (err) {
      logger.error('TBM 세션 완료 처리 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 완료 처리 중 오류가 발생했습니다.', error: err.message });
    }
  },

  deleteSession: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const result = await TbmModel.deleteSession(sessionId);

      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: 'TBM 세션을 찾을 수 없거나 이미 완료된 세션입니다.' });
      }

      res.json({ success: true, message: 'TBM 세션이 삭제되었습니다.' });
    } catch (err) {
      logger.error('TBM 세션 삭제 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 세션 삭제 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 팀 구성 관련 ====================

  addTeamMember: async (req, res) => {
    try {
      const assignmentData = {
        session_id: req.params.sessionId,
        user_id: req.body.user_id,
        assigned_role: req.body.assigned_role || null,
        work_detail: req.body.work_detail || null,
        is_present: req.body.is_present,
        absence_reason: req.body.absence_reason || null,
        project_id: req.body.project_id || null,
        work_type_id: req.body.work_type_id || null,
        task_id: req.body.task_id || null,
        workplace_category_id: req.body.workplace_category_id || null,
        workplace_id: req.body.workplace_id || null,
        work_hours: req.body.work_hours !== undefined ? req.body.work_hours : undefined
      };

      if (!assignmentData.user_id) {
        return res.status(400).json({ success: false, message: '작업자 ID가 필요합니다.' });
      }

      await TbmModel.addTeamMember(assignmentData);
      res.json({ success: true, message: '팀원이 추가되었습니다.' });
    } catch (err) {
      logger.error('팀원 추가 오류:', err);
      res.status(500).json({ success: false, message: '팀원 추가 중 오류가 발생했습니다.', error: err.message });
    }
  },

  addSplitAssignment: async (req, res) => {
    try {
      const assignmentData = {
        session_id: req.params.sessionId,
        user_id: req.body.user_id,
        work_hours: req.body.work_hours,
        project_id: req.body.project_id || null,
        work_type_id: req.body.work_type_id || null,
        task_id: req.body.task_id || null,
        workplace_category_id: req.body.workplace_category_id || null,
        workplace_id: req.body.workplace_id || null
      };

      if (!assignmentData.user_id || !assignmentData.work_hours) {
        return res.status(400).json({ success: false, message: '작업자 ID와 작업시간이 필요합니다.' });
      }

      const result = await TbmModel.addSplitAssignment(assignmentData);
      res.json({ success: true, data: result });
    } catch (err) {
      logger.error('분할 항목 추가 오류:', err);
      res.status(500).json({ success: false, message: '분할 항목 추가 중 오류가 발생했습니다.' });
    }
  },

  addTeamMembers: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const { members } = req.body;

      if (!Array.isArray(members) || members.length === 0) {
        return res.status(400).json({ success: false, message: '팀원 목록이 필요합니다.' });
      }

      // 중복 배정 검증
      const sessionRows = await TbmModel.getSessionById(sessionId);
      if (sessionRows.length > 0) {
        const sessionDate = sessionRows[0].session_date;
        let dateStr;
        if (sessionDate instanceof Date) {
          dateStr = sessionDate.toISOString().split('T')[0];
        } else if (typeof sessionDate === 'string') {
          dateStr = sessionDate.split('T')[0];
        } else {
          dateStr = new Date(sessionDate).toISOString().split('T')[0];
        }

        const userIds = members.map(m => m.user_id);
        const duplicates = await TbmModel.checkDuplicateAssignments(dateStr, userIds, sessionId);

        if (duplicates.length > 0) {
          const names = duplicates.map(d => d.worker_name).join(', ');
          return res.status(409).json({
            success: false,
            message: `다음 작업자가 이미 다른 TBM에 배정되어 있습니다: ${names}`,
            duplicates: duplicates
          });
        }
      }

      await TbmModel.addTeamMembers(sessionId, members);
      res.json({
        success: true,
        message: `${members.length}명의 팀원이 추가되었습니다.`,
        data: { count: members.length }
      });
    } catch (err) {
      logger.error('팀 구성 일괄 추가 오류:', err);
      res.status(500).json({ success: false, message: '팀 구성 추가 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getTeamMembers: async (req, res) => {
    try {
      const results = await TbmModel.getTeamMembers(req.params.sessionId);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('팀 구성 조회 오류:', err);
      res.status(500).json({ success: false, message: '팀 구성 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  removeTeamMember: async (req, res) => {
    try {
      const { sessionId, userId } = req.params;
      const result = await TbmModel.removeTeamMember(sessionId, userId);

      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: '팀원을 찾을 수 없습니다.' });
      }

      res.json({ success: true, message: '팀원이 제거되었습니다.' });
    } catch (err) {
      logger.error('팀원 제거 오류:', err);
      res.status(500).json({ success: false, message: '팀원 제거 중 오류가 발생했습니다.', error: err.message });
    }
  },

  clearAllTeamMembers: async (req, res) => {
    try {
      const result = await TbmModel.clearAllTeamMembers(req.params.sessionId);
      res.json({
        success: true,
        message: '모든 팀원이 삭제되었습니다.',
        data: { deletedCount: result.affectedRows }
      });
    } catch (err) {
      logger.error('팀원 전체 삭제 오류:', err);
      res.status(500).json({ success: false, message: '팀원 전체 삭제 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 안전 체크리스트 관련 ====================

  getAllSafetyChecks: async (req, res) => {
    try {
      const results = await TbmModel.getAllSafetyChecks();
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('안전 체크 항목 조회 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 항목 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getSafetyRecords: async (req, res) => {
    try {
      const results = await TbmModel.getSafetyRecords(req.params.sessionId);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('안전 체크 기록 조회 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 기록 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  saveSafetyRecords: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const { records } = req.body;

      if (!Array.isArray(records) || records.length === 0) {
        return res.status(400).json({ success: false, message: '안전 체크 기록이 필요합니다.' });
      }

      await TbmModel.saveSafetyRecords(sessionId, records, req.user.user_id);
      res.json({
        success: true,
        message: '안전 체크가 저장되었습니다.',
        data: { count: records.length }
      });
    } catch (err) {
      logger.error('안전 체크 저장 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 저장 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 필터링된 안전 체크리스트 (확장) ====================

  getFilteredSafetyChecks: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const weatherService = require('../services/weatherService');
      let weatherRecord = await weatherService.getWeatherRecord(sessionId);
      let weatherConditions = [];

      if (weatherRecord && weatherRecord.weather_conditions) {
        weatherConditions = weatherRecord.weather_conditions;
      } else {
        const currentWeather = await weatherService.getCurrentWeather();
        weatherConditions = await weatherService.determineWeatherConditions(currentWeather);
        await weatherService.saveWeatherRecord(sessionId, currentWeather, weatherConditions);
      }

      const results = await TbmModel.getFilteredSafetyChecks(sessionId, weatherConditions);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('필터링된 안전 체크 조회 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크리스트 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getCurrentWeather: async (req, res) => {
    try {
      const weatherService = require('../services/weatherService');
      const { nx, ny } = req.query;

      const weatherData = await weatherService.getCurrentWeather(nx, ny);
      const conditions = await weatherService.determineWeatherConditions(weatherData);
      const conditionList = await weatherService.getWeatherConditionList();

      const activeConditions = conditionList.filter(c => conditions.includes(c.condition_code));

      res.json({
        success: true,
        data: { ...weatherData, conditions, conditionDetails: activeConditions }
      });
    } catch (err) {
      logger.error('날씨 조회 오류:', err);
      res.status(500).json({ success: false, message: '날씨 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  saveSessionWeather: async (req, res) => {
    try {
      const { sessionId } = req.params;
      const { weatherConditions } = req.body;
      const weatherService = require('../services/weatherService');

      const weatherData = await weatherService.getCurrentWeather();
      const conditions = weatherConditions || await weatherService.determineWeatherConditions(weatherData);
      await weatherService.saveWeatherRecord(sessionId, weatherData, conditions);

      res.json({ success: true, message: '날씨 정보가 저장되었습니다.', data: { conditions } });
    } catch (err) {
      logger.error('날씨 저장 오류:', err);
      res.status(500).json({ success: false, message: '날씨 저장 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getSessionWeather: async (req, res) => {
    try {
      const weatherService = require('../services/weatherService');
      const weatherRecord = await weatherService.getWeatherRecord(req.params.sessionId);

      if (!weatherRecord) {
        return res.status(404).json({ success: false, message: '날씨 기록이 없습니다.' });
      }

      res.json({ success: true, data: weatherRecord });
    } catch (err) {
      logger.error('날씨 조회 오류:', err);
      res.status(500).json({ success: false, message: '날씨 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getWeatherConditions: async (req, res) => {
    try {
      const weatherService = require('../services/weatherService');
      const conditions = await weatherService.getWeatherConditionList();
      res.json({ success: true, data: conditions });
    } catch (err) {
      logger.error('날씨 조건 조회 오류:', err);
      res.status(500).json({ success: false, message: '날씨 조건 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 안전 체크항목 관리 (관리자용) ====================

  createSafetyCheck: async (req, res) => {
    try {
      const checkData = req.body;
      if (!checkData.check_category || !checkData.check_item) {
        return res.status(400).json({ success: false, message: '카테고리와 체크 항목은 필수입니다.' });
      }

      const result = await TbmModel.createSafetyCheck(checkData);
      res.status(201).json({
        success: true,
        message: '안전 체크 항목이 생성되었습니다.',
        data: { check_id: result.insertId }
      });
    } catch (err) {
      logger.error('안전 체크 항목 생성 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 항목 생성 중 오류가 발생했습니다.', error: err.message });
    }
  },

  updateSafetyCheck: async (req, res) => {
    try {
      const result = await TbmModel.updateSafetyCheck(req.params.checkId, req.body);
      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: '안전 체크 항목을 찾을 수 없습니다.' });
      }
      res.json({ success: true, message: '안전 체크 항목이 수정되었습니다.' });
    } catch (err) {
      logger.error('안전 체크 항목 수정 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 항목 수정 중 오류가 발생했습니다.', error: err.message });
    }
  },

  deleteSafetyCheck: async (req, res) => {
    try {
      const result = await TbmModel.deleteSafetyCheck(req.params.checkId);
      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: '안전 체크 항목을 찾을 수 없습니다.' });
      }
      res.json({ success: true, message: '안전 체크 항목이 삭제되었습니다.' });
    } catch (err) {
      logger.error('안전 체크 항목 삭제 오류:', err);
      res.status(500).json({ success: false, message: '안전 체크 항목 삭제 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 작업 인계 관련 ====================

  createHandover: async (req, res) => {
    try {
      const handoverData = {
        session_id: req.body.session_id,
        from_leader_user_id: req.body.from_leader_user_id,
        to_leader_user_id: req.body.to_leader_user_id,
        handover_date: req.body.handover_date,
        handover_time: req.body.handover_time || null,
        reason: req.body.reason,
        handover_notes: req.body.handover_notes || null,
        user_ids: req.body.user_ids || []
      };

      if (!handoverData.session_id || !handoverData.from_leader_user_id ||
          !handoverData.to_leader_user_id || !handoverData.handover_date || !handoverData.reason) {
        return res.status(400).json({ success: false, message: '필수 정보가 누락되었습니다.' });
      }

      const result = await TbmModel.createHandover(handoverData);
      res.status(201).json({
        success: true,
        message: '작업 인계가 생성되었습니다.',
        data: { handover_id: result.insertId }
      });
    } catch (err) {
      logger.error('작업 인계 생성 오류:', err);
      res.status(500).json({ success: false, message: '작업 인계 생성 중 오류가 발생했습니다.', error: err.message });
    }
  },

  confirmHandover: async (req, res) => {
    try {
      const result = await TbmModel.confirmHandover(req.params.handoverId, req.user.user_id);
      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: '작업 인계 건을 찾을 수 없습니다.' });
      }
      res.json({ success: true, message: '작업 인계가 확인되었습니다.' });
    } catch (err) {
      logger.error('작업 인계 확인 오류:', err);
      res.status(500).json({ success: false, message: '작업 인계 확인 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getHandoversByDate: async (req, res) => {
    try {
      const results = await TbmModel.getHandoversByDate(req.params.date);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('작업 인계 목록 조회 오류:', err);
      res.status(500).json({ success: false, message: '작업 인계 목록 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getMyPendingHandovers: async (req, res) => {
    try {
      const toLeaderId = req.user.user_id;
      if (!toLeaderId) {
        return res.status(400).json({ success: false, message: '작업자 정보를 찾을 수 없습니다.' });
      }

      const results = await TbmModel.getPendingHandovers(toLeaderId);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('미확인 인계 건 조회 오류:', err);
      res.status(500).json({ success: false, message: '미확인 인계 건 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 통계 및 리포트 ====================

  getTbmStatistics: async (req, res) => {
    try {
      const { startDate, endDate } = req.query;
      if (!startDate || !endDate) {
        return res.status(400).json({ success: false, message: '시작일과 종료일이 필요합니다.' });
      }

      const results = await TbmModel.getTbmStatistics(startDate, endDate);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('TBM 통계 조회 오류:', err);
      res.status(500).json({ success: false, message: 'TBM 통계 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getLeaderStatistics: async (req, res) => {
    try {
      const { startDate, endDate } = req.query;
      if (!startDate || !endDate) {
        return res.status(400).json({ success: false, message: '시작일과 종료일이 필요합니다.' });
      }

      const results = await TbmModel.getLeaderStatistics(startDate, endDate);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('리더 통계 조회 오류:', err);
      res.status(500).json({ success: false, message: '리더 통계 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  // ==================== 작업자 이동 관련 ====================

  createTransfer: async (req, res) => {
    try {
      const { transfer_type, user_id, source_session_id, dest_session_id, hours,
              project_id, work_type_id, task_id, workplace_category_id, workplace_id } = req.body;

      if (!transfer_type || !user_id || !source_session_id || !dest_session_id || !hours) {
        return res.status(400).json({ success: false, message: '필수 정보가 누락되었습니다.' });
      }

      const today = new Date();
      const transferDate = today.getFullYear() + '-' +
        String(today.getMonth() + 1).padStart(2, '0') + '-' +
        String(today.getDate()).padStart(2, '0');

      const transferData = {
        transfer_type, user_id, source_session_id, dest_session_id,
        hours, initiated_by: req.user.user_id, transfer_date: transferDate,
        project_id, work_type_id, task_id, workplace_category_id, workplace_id
      };

      const result = await TbmTransferModel.createTransfer(transferData);
      if (!result.success) {
        return res.status(400).json(result);
      }

      res.json({ success: true, message: '이동이 완료되었습니다.', data: result });
    } catch (err) {
      logger.error('이동 실행 오류:', err);
      res.status(500).json({ success: false, message: '이동 실행 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getTransfersByDate: async (req, res) => {
    try {
      const results = await TbmTransferModel.getTransfersByDate(req.params.date);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('이동 내역 조회 오류:', err);
      res.status(500).json({ success: false, message: '이동 내역 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  cancelTransfer: async (req, res) => {
    try {
      const result = await TbmTransferModel.cancelTransfer(req.params.transferId);
      if (!result.success) {
        return res.status(400).json(result);
      }
      res.json({ success: true, message: '이동이 취소되었습니다.' });
    } catch (err) {
      logger.error('이동 취소 오류:', err);
      res.status(500).json({ success: false, message: '이동 취소 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getWorkerAssignmentsByDate: async (req, res) => {
    try {
      const results = await TbmTransferModel.getWorkerAssignmentsByDate(req.params.date);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('배정 현황 조회 오류:', err);
      res.status(500).json({ success: false, message: '배정 현황 조회 중 오류가 발생했습니다.', error: err.message });
    }
  },

  getIncompleteWorkReports: async (req, res) => {
    try {
      const userId = req.user.user_id;
      const accessLevel = req.user.access_level;
      const filterUserId = (accessLevel === 'system' || accessLevel === 'admin') ? null : userId;

      const results = await TbmModel.getIncompleteWorkReports(filterUserId);
      res.json({ success: true, data: results });
    } catch (err) {
      logger.error('미완료 작업보고서 조회 오류:', err);
      res.status(500).json({ success: false, message: '미완료 작업보고서 조회 중 오류가 발생했습니다.', error: err.message });
    }
  }
};

module.exports = TbmController;
