// models/monthlyComparisonModel.js — 월간 비교·확인·정산
const { getDb } = require('../dbPool');

const MonthlyComparisonModel = {
  // 1. 작업보고서 일별 합산
  async getWorkReports(userId, year, month) {
    const db = await getDb();
    const [rows] = await db.query(`
      SELECT
        dwr.report_date,
        SUM(dwr.work_hours) AS total_hours,
        GROUP_CONCAT(DISTINCT p.project_name SEPARATOR ', ') AS project_names,
        GROUP_CONCAT(DISTINCT wt.name SEPARATOR ', ') AS work_type_names
      FROM daily_work_reports dwr
      LEFT JOIN projects p ON dwr.project_id = p.project_id
      LEFT JOIN work_types wt ON dwr.work_type_id = wt.id
      WHERE dwr.user_id = ?
        AND YEAR(dwr.report_date) = ?
        AND MONTH(dwr.report_date) = ?
      GROUP BY dwr.report_date
      ORDER BY dwr.report_date
    `, [userId, year, month]);
    return rows;
  },

  // 2. 근태관리 일별 기록
  async getAttendanceRecords(userId, year, month) {
    const db = await getDb();
    const [rows] = await db.query(`
      SELECT
        dar.record_date,
        dar.total_work_hours,
        dar.attendance_type_id,
        dar.vacation_type_id,
        dar.status,
        dar.is_present,
        dar.notes,
        wat.type_name AS attendance_type_name,
        vt.type_name AS vacation_type_name
      FROM daily_attendance_records dar
      LEFT JOIN work_attendance_types wat ON dar.attendance_type_id = wat.id
      LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
      WHERE dar.user_id = ?
        AND YEAR(dar.record_date) = ?
        AND MONTH(dar.record_date) = ?
      ORDER BY dar.record_date
    `, [userId, year, month]);
    return rows;
  },

  // 3. 확인 상태 조회
  async getConfirmation(userId, year, month) {
    const db = await getDb();
    const [rows] = await db.query(
      'SELECT * FROM monthly_work_confirmations WHERE user_id = ? AND year = ? AND month = ?',
      [userId, year, month]
    );
    return rows[0] || null;
  },

  // 4. 확인 UPSERT + 반려 시 알림 (단일 트랜잭션)
  async upsertConfirmation(data, notificationData) {
    const db = await getDb();
    const conn = await db.getConnection();
    try {
      await conn.beginTransaction();

      // 기존 상태 체크
      const [existing] = await conn.query(
        'SELECT id, status FROM monthly_work_confirmations WHERE user_id = ? AND year = ? AND month = ?',
        [data.user_id, data.year, data.month]
      );
      if (existing.length > 0 && existing[0].status === 'confirmed') {
        await conn.rollback();
        return { error: '이미 확인된 내역은 변경할 수 없습니다.' };
      }

      // UPSERT
      const [result] = await conn.query(`
        INSERT INTO monthly_work_confirmations
          (user_id, year, month, status, total_work_days, total_work_hours,
           total_overtime_hours, vacation_days, mismatch_count, reject_reason,
           confirmed_at, rejected_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
          status = VALUES(status),
          total_work_days = VALUES(total_work_days),
          total_work_hours = VALUES(total_work_hours),
          total_overtime_hours = VALUES(total_overtime_hours),
          vacation_days = VALUES(vacation_days),
          mismatch_count = VALUES(mismatch_count),
          reject_reason = VALUES(reject_reason),
          confirmed_at = VALUES(confirmed_at),
          rejected_at = VALUES(rejected_at)
      `, [
        data.user_id, data.year, data.month, data.status,
        data.total_work_days || 0, data.total_work_hours || 0,
        data.total_overtime_hours || 0, data.vacation_days || 0,
        data.mismatch_count || 0, data.reject_reason || null,
        data.status === 'confirmed' ? new Date() : null,
        data.status === 'rejected' ? new Date() : null
      ]);

      const confirmationId = result.insertId || (existing.length > 0 ? existing[0].id : null);

      // 반려 시 알림 생성
      if (data.status === 'rejected' && notificationData && confirmationId) {
        const { recipients, title, message, linkUrl, createdBy } = notificationData;
        for (const recipientId of recipients) {
          await conn.query(`
            INSERT INTO notifications
              (user_id, type, title, message, link_url, reference_type, reference_id, is_read, created_by)
            VALUES (?, 'system', ?, ?, ?, 'monthly_work_confirmation', ?, 0, ?)
          `, [recipientId, title, message, linkUrl, confirmationId, createdBy]);
        }
      }

      await conn.commit();
      return { id: confirmationId, status: data.status };
    } catch (err) {
      await conn.rollback();
      throw err;
    } finally {
      conn.release();
    }
  },

  // 5. 전체 작업자 확인 현황
  async getAllStatus(year, month, departmentId) {
    const db = await getDb();
    let sql = `
      SELECT
        w.user_id, w.worker_name, w.job_type,
        COALESCE(d.department_name, '미배정') AS department_name,
        COALESCE(mwc.status, 'pending') AS status,
        mwc.confirmed_at, mwc.rejected_at, mwc.reject_reason,
        mwc.total_work_days, mwc.total_work_hours,
        mwc.total_overtime_hours, mwc.vacation_days, mwc.mismatch_count
      FROM workers w
      LEFT JOIN departments d ON w.department_id = d.department_id
      LEFT JOIN monthly_work_confirmations mwc
        ON w.user_id = mwc.user_id AND mwc.year = ? AND mwc.month = ?
      WHERE w.status = 'active'
    `;
    const params = [year, month];
    if (departmentId) {
      sql += ' AND w.department_id = ?';
      params.push(departmentId);
    }
    sql += ' ORDER BY d.department_name, w.worker_name';

    const [rows] = await db.query(sql, params);
    return rows;
  },

  // 6. 지원팀 사용자 목록 (알림 수신자)
  async getSupportTeamUsers() {
    const db = await getDb();
    const [rows] = await db.query(
      "SELECT user_id FROM sso_users WHERE role IN ('support_team', 'admin', 'system') AND is_active = 1"
    );
    return rows.map(r => r.user_id);
  },

  // 7. 엑셀용 전체 일별 상세
  async getExcelData(year, month) {
    const db = await getDb();
    const [rows] = await db.query(`
      SELECT
        w.worker_name, d.department_name, w.job_type,
        dar.record_date,
        dar.total_work_hours AS attendance_hours,
        wat.type_name AS attendance_type_name,
        vt.type_name AS vacation_type_name,
        COALESCE(wr.total_hours, 0) AS report_hours
      FROM workers w
      LEFT JOIN departments d ON w.department_id = d.department_id
      LEFT JOIN daily_attendance_records dar
        ON w.user_id = dar.user_id
        AND YEAR(dar.record_date) = ? AND MONTH(dar.record_date) = ?
      LEFT JOIN work_attendance_types wat ON dar.attendance_type_id = wat.id
      LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
      LEFT JOIN (
        SELECT user_id, report_date, SUM(work_hours) AS total_hours
        FROM daily_work_reports
        WHERE YEAR(report_date) = ? AND MONTH(report_date) = ?
        GROUP BY user_id, report_date
      ) wr ON w.user_id = wr.user_id AND dar.record_date = wr.report_date
      WHERE w.status = 'active'
      ORDER BY d.department_name, w.worker_name, dar.record_date
    `, [year, month, year, month]);
    return rows;
  },

  // 8. 작업자 정보
  async getWorkerInfo(userId) {
    const db = await getDb();
    const [rows] = await db.query(`
      SELECT w.user_id, w.worker_name, w.job_type,
             COALESCE(d.department_name, '미배정') AS department_name
      FROM workers w
      LEFT JOIN departments d ON w.department_id = d.department_id
      WHERE w.user_id = ?
    `, [userId]);
    return rows[0] || null;
  }
};

module.exports = MonthlyComparisonModel;
