const dailyWorkReportModel = require('../models/dailyWorkReportModel');

/**
 * 일일 작업 보고서를 생성하는 비즈니스 로직을 처리합니다.
 * @param {object} reportData - 컨트롤러에서 전달된 보고서 데이터
 * @returns {Promise<object>} 생성 결과 또는 에러
 */
const createDailyWorkReportService = async (reportData) => {
  const { report_date, worker_id, work_entries, created_by, created_by_name } = reportData;

  // 1. 기본 유효성 검사
  if (!report_date || !worker_id || !work_entries) {
    throw new Error('필수 필드(report_date, worker_id, work_entries)가 누락되었습니다.');
  }

  if (!Array.isArray(work_entries) || work_entries.length === 0) {
    throw new Error('최소 하나의 작업 항목(work_entries)이 필요합니다.');
  }

  if (!created_by) {
    throw new Error('사용자 인증 정보(created_by)가 없습니다.');
  }

  // 2. 작업 항목 유효성 검사
  for (let i = 0; i < work_entries.length; i++) {
    const entry = work_entries[i];
    const requiredFields = ['project_id', 'task_id', 'work_hours'];
    
    for (const field of requiredFields) {
      if (entry[field] === undefined || entry[field] === null || entry[field] === '') {
        throw new Error(`작업 항목 ${i + 1}의 '${field}' 필드가 누락되었습니다.`);
      }
    }
    
    // is_error가 true일 때 error_type_code_id 필수 검사
    if (entry.is_error === true && !entry.error_type_code_id) {
        throw new Error(`작업 항목 ${i + 1}이 에러 상태인 경우 'error_type_code_id'가 필요합니다.`);
    }

    const hours = parseFloat(entry.work_hours);
    if (isNaN(hours) || hours <= 0 || hours > 24) {
      throw new Error(`작업 항목 ${i + 1}의 작업 시간이 유효하지 않습니다 (0 초과 24 이하).`);
    }
  }

  // 3. 모델에 전달할 데이터 준비
  const modelData = {
    report_date,
    worker_id: parseInt(worker_id),
    entries: work_entries.map(entry => ({
      project_id: entry.project_id,
      task_id: entry.task_id,
      work_hours: parseFloat(entry.work_hours),
      is_error: entry.is_error || false,
      error_type_code_id: entry.error_type_code_id || null,
      created_by_user_id: created_by
    }))
  };

  console.log('📝 [Service] 작업보고서 생성 요청:', {
    date: report_date,
    worker: worker_id,
    creator: created_by_name,
    entries_count: modelData.entries.length
  });

  // 4. 모델 함수 호출
  try {
    const result = await dailyWorkReportModel.createReportEntries(modelData);
    console.log('✅ [Service] 작업보고서 생성 성공:', result);
    return {
      message: '작업보고서가 성공적으로 생성되었습니다.',
      ...result
    };
  } catch (error) {
    console.error('[Service] 작업보고서 생성 중 오류 발생:', error);
    // 모델에서 발생한 오류를 그대로 상위로 전달
    throw error;
  }
};

/**
 * 사용자 권한과 요청 파라미터에 따라 일일 작업 보고서를 조회하는 비즈니스 로직을 처리합니다.
 * @param {object} queryParams - 컨트롤러에서 전달된 쿼리 파라미터
 * @param {object} userInfo - 요청을 보낸 사용자의 정보 (id, role 등)
 * @returns {Promise<Array>} 조회된 작업 보고서 배열
 */
const getDailyWorkReportsService = async (queryParams, userInfo) => {
  const { date, worker_id, created_by: requested_created_by, view_all } = queryParams;
  const { user_id: current_user_id, role } = userInfo;

  if (!date) {
    throw new Error('조회를 위해 날짜(date)는 필수입니다.');
  }

  // 관리자 여부 확인
  const isAdmin = role === 'system' || role === 'admin';
  const canViewAll = isAdmin || view_all === 'true';

  // 모델에 전달할 조회 옵션 객체 생성
  const options = { date };

  if (worker_id) {
    options.worker_id = parseInt(worker_id);
  }
  
  // 최종적으로 필터링할 작성자 ID 결정
  if (!canViewAll) {
    // 관리자가 아니면 자신의 데이터만 보거나, 명시적으로 요청된 자신의 ID만 허용
    options.created_by_user_id = requested_created_by ? Math.min(requested_created_by, current_user_id) : current_user_id;
  } else if (requested_created_by) {
    // 관리자는 다른 사람의 데이터도 조회 가능
    options.created_by_user_id = parseInt(requested_created_by);
  }
  // created_by_user_id가 명시되지 않으면 모든 작성자의 데이터를 조회

  console.log('📊 [Service] 작업보고서 조회 요청:', { ...options, requester: current_user_id, isAdmin });

  try {
    // 모델 함수 호출
    const reports = await dailyWorkReportModel.getReportsWithOptions(options);
    console.log(`✅ [Service] 작업보고서 ${reports.length}개 조회 성공`);
    return reports;
  } catch (error) {
    console.error('[Service] 작업보고서 조회 중 오류 발생:', error);
    throw error;
  }
};

/**
 * 특정 작업 보고서 항목을 수정하는 비즈니스 로직을 처리합니다.
 * @param {string} reportId - 수정할 보고서의 ID
 * @param {object} updateData - 수정할 데이터
 * @param {object} userInfo - 요청을 보낸 사용자의 정보
 * @returns {Promise<object>} 수정 결과
 */
const updateWorkReportService = async (reportId, updateData, userInfo) => {
  const { user_id: updated_by } = userInfo;

  if (!reportId || !updateData || Object.keys(updateData).length === 0) {
    throw new Error('수정을 위해 보고서 ID와 수정할 데이터가 필요합니다.');
  }

  const modelUpdateData = { ...updateData, updated_by_user_id: updated_by };

  console.log(`✏️ [Service] 작업보고서 수정 요청: id=${reportId}`);

  try {
    const affectedRows = await dailyWorkReportModel.updateReportById(reportId, modelUpdateData);

    if (affectedRows === 0) {
      // 에러를 발생시켜 컨트롤러에서 404 처리를 할 수 있도록 함
      const notFoundError = new Error('수정할 작업보고서를 찾을 수 없습니다.');
      notFoundError.statusCode = 404;
      throw notFoundError;
    }

    console.log(`✅ [Service] 작업보고서 수정 성공: id=${reportId}`);
    return {
      message: '작업보고서가 성공적으로 수정되었습니다.',
      report_id: reportId,
      affected_rows: affectedRows
    };
  } catch (error) {
    console.error(`[Service] 작업보고서 수정 중 오류 발생 (id: ${reportId}):`, error);
    throw error;
  }
};

/**
 * 특정 작업 보고서 항목을 삭제하는 비즈니스 로직을 처리합니다.
 * @param {string} reportId - 삭제할 보고서의 ID
 * @param {object} userInfo - 요청을 보낸 사용자의 정보
 * @returns {Promise<object>} 삭제 결과
 */
const removeDailyWorkReportService = async (reportId, userInfo) => {
  const { user_id: deleted_by } = userInfo;

  if (!reportId) {
    throw new Error('삭제를 위해 보고서 ID가 필요합니다.');
  }

  console.log(`🗑️ [Service] 작업보고서 삭제 요청: id=${reportId}`);

  try {
    // 모델 함수는 삭제 전 권한 검사를 위해 deleted_by 정보를 받을 수 있습니다 (현재 모델에서는 미사용).
    const affectedRows = await dailyWorkReportModel.removeReportById(reportId, deleted_by);

    if (affectedRows === 0) {
      const notFoundError = new Error('삭제할 작업보고서를 찾을 수 없습니다.');
      notFoundError.statusCode = 404;
      throw notFoundError;
    }

    console.log(`✅ [Service] 작업보고서 삭제 성공: id=${reportId}`);
    return {
      message: '작업보고서가 성공적으로 삭제되었습니다.',
      report_id: reportId,
      affected_rows: affectedRows
    };
  } catch (error) {
    console.error(`[Service] 작업보고서 삭제 중 오류 발생 (id: ${reportId}):`, error);
    throw error;
  }
};


module.exports = {
  createDailyWorkReportService,
  getDailyWorkReportsService,
  updateWorkReportService,
  removeDailyWorkReportService,
}; 