/**
 * vacationBalanceController.js
 * 휴가 잔액 관련 컨트롤러
 */

const vacationBalanceModel = require('../models/vacationBalanceModel');
const vacationTypeModel = require('../models/vacationTypeModel');
const logger = require('../utils/logger');

const vacationBalanceController = {
  /**
   * 특정 작업자의 휴가 잔액 조회 (특정 연도)
   * GET /api/vacation-balances/user/:userId/year/:year
   */
  async getByWorkerAndYear(req, res) {
    try {
      const { userId, year } = req.params;
      const results = await vacationBalanceModel.getByWorkerAndYear(userId, year);
      res.json({ success: true, data: results });
    } catch (error) {
      logger.error('휴가 잔액 조회 오류:', error);
      res.status(500).json({ success: false, message: '휴가 잔액을 조회하는 중 오류가 발생했습니다' });
    }
  },

  /**
   * 모든 작업자의 휴가 잔액 조회 (특정 연도)
   * GET /api/vacation-balances/year/:year
   */
  async getAllByYear(req, res) {
    try {
      const { year } = req.params;
      const results = await vacationBalanceModel.getAllByYear(year);
      res.json({ success: true, data: results });
    } catch (error) {
      logger.error('전체 휴가 잔액 조회 오류:', error);
      res.status(500).json({ success: false, message: '전체 휴가 잔액을 조회하는 중 오류가 발생했습니다' });
    }
  },

  /**
   * 휴가 잔액 생성
   * POST /api/vacation-balances
   */
  async createBalance(req, res) {
    try {
      const { user_id, vacation_type_id, year, total_days, used_days, notes } = req.body;
      const created_by = req.user.user_id;

      if (!user_id || !vacation_type_id || !year || total_days === undefined) {
        return res.status(400).json({
          success: false,
          message: '필수 필드가 누락되었습니다 (user_id, vacation_type_id, year, total_days)'
        });
      }

      // 중복 체크
      const existing = await vacationBalanceModel.getByWorkerTypeYear(user_id, vacation_type_id, year);
      if (existing && existing.length > 0) {
        return res.status(400).json({
          success: false,
          message: '이미 해당 작업자의 해당 연도 휴가 잔액이 존재합니다'
        });
      }

      const balanceData = {
        user_id,
        vacation_type_id,
        year,
        total_days,
        used_days: used_days || 0,
        notes: notes || null,
        created_by
      };

      const result = await vacationBalanceModel.create(balanceData);
      res.status(201).json({
        success: true,
        message: '휴가 잔액이 생성되었습니다',
        data: { id: result.insertId }
      });
    } catch (error) {
      logger.error('휴가 잔액 생성 오류:', error);
      res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
    }
  },

  /**
   * 휴가 잔액 수정
   * PUT /api/vacation-balances/:id
   */
  async updateBalance(req, res) {
    try {
      const { id } = req.params;
      const { total_days, used_days, notes } = req.body;

      const updateData = {};
      if (total_days !== undefined) updateData.total_days = total_days;
      if (used_days !== undefined) updateData.used_days = used_days;
      if (notes !== undefined) updateData.notes = notes;
      updateData.updated_at = new Date();

      if (Object.keys(updateData).length === 1) {
        return res.status(400).json({ success: false, message: '수정할 데이터가 없습니다' });
      }

      const result = await vacationBalanceModel.update(id, updateData);
      if (result.affectedRows === 0) {
        return res.status(404).json({ success: false, message: '휴가 잔액을 찾을 수 없습니다' });
      }

      res.json({ success: true, message: '휴가 잔액이 수정되었습니다' });
    } catch (error) {
      logger.error('휴가 잔액 수정 오류:', error);
      res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
    }
  },

  /**
   * 휴가 잔액 삭제
   * DELETE /api/vacation-balances/:id
   */
  async deleteBalance(req, res) {
    try {
      const { id } = req.params;
      const result = await vacationBalanceModel.delete(id);

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

      res.json({ success: true, message: '휴가 잔액이 삭제되었습니다' });
    } catch (error) {
      logger.error('휴가 잔액 삭제 오류:', error);
      res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
    }
  },

  /**
   * 근속년수 기반 연차 자동 계산 및 생성
   * POST /api/vacation-balances/auto-calculate
   */
  async autoCalculateAndCreate(req, res) {
    try {
      const { user_id, hire_date, year } = req.body;
      const created_by = req.user.user_id;

      if (!user_id || !hire_date || !year) {
        return res.status(400).json({
          success: false,
          message: '필수 필드가 누락되었습니다 (user_id, hire_date, year)'
        });
      }

      const annualDays = vacationBalanceModel.calculateAnnualLeaveDays(hire_date, year);

      // ANNUAL 휴가 유형 ID 조회
      const types = await vacationTypeModel.getByCode('ANNUAL');
      if (!types || types.length === 0) {
        return res.status(500).json({ success: false, message: 'ANNUAL 휴가 유형을 찾을 수 없습니다' });
      }

      const annualTypeId = types[0].id;

      // 중복 체크
      const existing = await vacationBalanceModel.getByWorkerTypeYear(user_id, annualTypeId, year);
      if (existing && existing.length > 0) {
        return res.status(400).json({
          success: false,
          message: '이미 해당 작업자의 해당 연도 연차가 존재합니다'
        });
      }

      const balanceData = {
        user_id,
        vacation_type_id: annualTypeId,
        year,
        total_days: annualDays,
        used_days: 0,
        notes: `근속년수 기반 자동 계산 (입사일: ${hire_date})`,
        created_by
      };

      const result = await vacationBalanceModel.create(balanceData);
      res.status(201).json({
        success: true,
        message: `${annualDays}일의 연차가 자동으로 생성되었습니다`,
        data: { id: result.insertId, calculated_days: annualDays }
      });
    } catch (error) {
      logger.error('연차 자동 계산 오류:', error);
      res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
    }
  },

  /**
   * 휴가 잔액 일괄 저장 (upsert)
   * POST /api/vacation-balances/bulk-upsert
   */
  async bulkUpsert(req, res) {
    try {
      const { balances } = req.body;
      const created_by = req.user.user_id;

      if (!balances || !Array.isArray(balances) || balances.length === 0) {
        return res.status(400).json({ success: false, message: '저장할 데이터가 없습니다' });
      }

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

      let successCount = 0;
      let errorCount = 0;

      for (const balance of balances) {
        const { user_id, vacation_type_id, year, total_days, notes } = balance;

        if (!user_id || !vacation_type_id || !year || total_days === undefined) {
          errorCount++;
          continue;
        }

        try {
          const query = `
            INSERT INTO vacation_balance_details
              (user_id, vacation_type_id, year, total_days, used_days, notes, created_by)
            VALUES (?, ?, ?, ?, 0, ?, ?)
            ON DUPLICATE KEY UPDATE
              total_days = VALUES(total_days),
              notes = VALUES(notes),
              updated_at = NOW()
          `;

          await db.query(query, [user_id, vacation_type_id, year, total_days, notes || null, created_by]);
          successCount++;
        } catch (err) {
          logger.error('휴가 잔액 저장 오류:', err);
          errorCount++;
        }
      }

      res.json({
        success: true,
        message: `${successCount}건 저장 완료${errorCount > 0 ? `, ${errorCount}건 실패` : ''}`,
        data: { successCount, errorCount }
      });
    } catch (error) {
      logger.error('bulkUpsert 오류:', error);
      res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
    }
  },

  /**
   * 작업자의 사용 가능한 휴가 일수 조회
   * GET /api/vacation-balances/user/:userId/year/:year/available
   */
  async getAvailableDays(req, res) {
    try {
      const { userId, year } = req.params;
      const results = await vacationBalanceModel.getAvailableVacationDays(userId, year);
      res.json({ success: true, data: results });
    } catch (error) {
      logger.error('사용 가능 휴가 조회 오류:', error);
      res.status(500).json({ success: false, message: '사용 가능 휴가를 조회하는 중 오류가 발생했습니다' });
    }
  }
};

module.exports = vacationBalanceController;
