// models/monthlyStatusModel.js
// 월별 작업자 상태 집계 모델

const { getDb } = require('../dbPool');

class MonthlyStatusModel {
  // 월별 일자별 요약 조회 (캘린더용)
  static async getMonthlySummary(year, month) {
    const db = await getDb();

    try {
      const [rows] = await db.execute(`
        SELECT 
          date,
          total_workers,
          working_workers,
          incomplete_workers,
          partial_workers,
          complete_workers,
          overtime_workers,
          vacation_workers,
          error_workers,
          overtime_warning_workers,
          total_work_hours,
          total_work_count,
          total_error_count,
          has_issues,
          has_errors,
          has_overtime_warning,
          last_updated
        FROM monthly_summary 
        WHERE year = ? AND month = ?
        ORDER BY date ASC
      `, [year, month]);

      return rows;
    } catch (error) {
      console.error('월별 요약 조회 오류:', error);
      throw error;
    }
  }

  // 특정 날짜의 작업자별 상태 조회 (모달용)
  // ✅ 리팩토링: 집계 테이블 대신 daily_work_reports에서 직접 조회 (중복 문제 완전 해결)
  static async getDailyWorkerStatus(date) {
    const db = await getDb();

    try {
      // daily_work_reports에서 직접 집계하여 조회 (중복 없음 보장)
      const [rows] = await db.query(`
        SELECT 
          w.user_id,
          w.worker_name,
          w.job_type,
          YEAR(?) as year,
          MONTH(?) as month,
          ? as date,
          COALESCE(SUM(dwr.work_hours), 0) as total_work_hours,
          COALESCE(SUM(CASE WHEN dwr.project_id != 13 THEN dwr.work_hours ELSE 0 END), 0) as actual_work_hours,
          COALESCE(SUM(CASE WHEN dwr.project_id = 13 THEN dwr.work_hours ELSE 0 END), 0) as vacation_hours,
          COUNT(dwr.id) as total_work_count,
          COUNT(CASE WHEN dwr.project_id != 13 AND dwr.work_status_id != 2 THEN 1 END) as regular_work_count,
          COUNT(CASE WHEN dwr.work_status_id = 2 THEN 1 END) as error_work_count,
          CASE 
            WHEN MAX(CASE WHEN dwr.work_status_id = 2 THEN 1 ELSE 0 END) = 1 THEN 'error'
            WHEN SUM(dwr.work_hours) > 12 THEN 'overtime-warning'
            WHEN SUM(dwr.work_hours) > 8 THEN 'overtime'
            WHEN SUM(dwr.work_hours) = 8 THEN 'complete'
            WHEN SUM(dwr.work_hours) > 0 THEN 'partial'
            ELSE 'incomplete'
          END as work_status,
          MAX(CASE WHEN dwr.project_id = 13 THEN 1 ELSE 0 END) as has_vacation,
          MAX(CASE WHEN dwr.work_status_id = 2 THEN 1 ELSE 0 END) as has_error,
          CASE 
            WHEN SUM(dwr.work_hours) < 8 AND SUM(dwr.work_hours) > 0 THEN 1
            ELSE 0
          END as has_issues,
          MAX(dwr.created_at) as last_updated
        FROM workers w
        LEFT JOIN daily_work_reports dwr ON w.user_id = dwr.user_id AND dwr.report_date = ?
        WHERE w.status = 'active'
        GROUP BY w.user_id, w.worker_name, w.job_type
        ORDER BY w.worker_name ASC
      `, [date, date, date, date]);

      return rows;
    } catch (error) {
      console.error('일별 작업자 상태 조회 오류:', error);
      throw error;
    }
  }

  // 월별 집계 데이터 강제 재계산 (관리용)
  static async recalculateMonth(year, month) {
    const db = await getDb();

    try {
      // 해당 월의 모든 날짜와 작업자 조합을 찾아서 재계산
      const [workDates] = await db.execute(`
        SELECT DISTINCT report_date, user_id
        FROM daily_work_reports
        WHERE YEAR(report_date) = ? AND MONTH(report_date) = ?
      `, [year, month]);

      let updatedCount = 0;

      for (const { report_date, user_id } of workDates) {
        await db.execute('CALL UpdateMonthlyWorkerStatus(?, ?)', [report_date, user_id]);
        updatedCount++;
      }

      return { success: true, updatedCount };

    } catch (error) {
      console.error('월별 집계 재계산 오류:', error);
      throw error;
    }
  }

  // 특정 날짜 집계 강제 업데이트
  static async updateDateSummary(date, userId = null) {
    const db = await getDb();

    try {
      if (userId) {
        // 특정 작업자만 업데이트
        await db.execute('CALL UpdateMonthlyWorkerStatus(?, ?)', [date, userId]);
      } else {
        // 해당 날짜의 모든 작업자 업데이트
        const [workers] = await db.execute(`
          SELECT DISTINCT user_id
          FROM daily_work_reports
          WHERE report_date = ?
        `, [date]);

        for (const { user_id } of workers) {
          await db.execute('CALL UpdateMonthlyWorkerStatus(?, ?)', [date, user_id]);
        }
      }

      return { success: true };
    } catch (error) {
      console.error('날짜별 집계 업데이트 오류:', error);
      throw error;
    }
  }

  // 집계 테이블 상태 확인
  static async getStatusInfo() {
    const db = await getDb();

    try {
      const [summaryCount] = await db.execute(`
        SELECT 
          COUNT(*) as total_days,
          MIN(date) as earliest_date,
          MAX(date) as latest_date,
          MAX(last_updated) as last_update
        FROM monthly_summary
      `);

      const [workerStatusCount] = await db.execute(`
        SELECT 
          COUNT(*) as total_records,
          COUNT(DISTINCT user_id) as unique_workers,
          COUNT(DISTINCT date) as unique_dates,
          MAX(last_updated) as last_update
        FROM monthly_worker_status
      `);

      return {
        summary: summaryCount[0],
        workerStatus: workerStatusCount[0]
      };
    } catch (error) {
      console.error('집계 테이블 상태 확인 오류:', error);
      throw error;
    }
  }
}

module.exports = MonthlyStatusModel;
