/**
 * 대시보드 개인 요약 모델
 * Sprint 003 — 연차/연장근로/접근 페이지 통합 조회
 */
const { getDb } = require('../config/database');

const OVERTIME_THRESHOLD = 8; // 연장근로 기준 시간

const DashboardModel = {
  /**
   * 사용자 정보 조회 (쿼리 1 — 먼저 실행)
   */
  getUserInfo: async (userId) => {
    const db = await getDb();
    const [rows] = await db.execute(`
      SELECT u.user_id, u.name, u.role,
             w.worker_id, w.worker_name, w.job_type, w.department_id,
             COALESCE(d.department_name, '미배정') AS department_name
      FROM sso_users u
      LEFT JOIN workers w ON u.user_id = w.user_id
      LEFT JOIN departments d ON w.department_id = d.department_id
      WHERE u.user_id = ?
    `, [userId]);
    return rows[0] || null;
  },

  /**
   * 연차 현황 조회 (쿼리 2)
   */
  getVacationBalance: async (workerId, year) => {
    if (!workerId) return [];
    const db = await getDb();
    const [rows] = await db.execute(`
      SELECT vbd.vacation_type_id, vbd.total_days, vbd.used_days, vbd.remaining_days,
             vt.type_name, vt.type_code
      FROM vacation_balance_details vbd
      JOIN vacation_types vt ON vbd.vacation_type_id = vt.id
      WHERE vbd.worker_id = ? AND vbd.year = ?
      ORDER BY vt.priority
    `, [workerId, year]);
    return rows;
  },

  /**
   * 월간 연장근로 조회 (쿼리 3)
   */
  getMonthlyOvertime: async (userId, year, month) => {
    const db = await getDb();
    const [rows] = await db.execute(`
      SELECT
        COUNT(CASE WHEN dar.total_work_hours > ${OVERTIME_THRESHOLD} THEN 1 END) AS overtime_days,
        COALESCE(SUM(CASE WHEN dar.total_work_hours > ${OVERTIME_THRESHOLD} THEN dar.total_work_hours - ${OVERTIME_THRESHOLD} ELSE 0 END), 0) AS total_overtime_hours,
        COUNT(*) AS total_work_days,
        COALESCE(SUM(dar.total_work_hours), 0) AS total_work_hours,
        COALESCE(AVG(dar.total_work_hours), 0) AS avg_daily_hours
      FROM daily_attendance_records dar
      WHERE dar.user_id = ? AND YEAR(dar.record_date) = ? AND MONTH(dar.record_date) = ?
        AND dar.total_work_hours > 0
    `, [userId, year, month]);
    return rows[0] || { overtime_days: 0, total_overtime_hours: 0, total_work_days: 0, total_work_hours: 0, avg_daily_hours: 0 };
  },

  /**
   * 접근 가능 페이지 조회 (쿼리 4)
   */
  getQuickAccess: async (userId, departmentId, role) => {
    const db = await getDb();
    const isAdmin = ['admin', 'system'].includes((role || '').toLowerCase());

    // 모든 페이지 조회
    const [allPages] = await db.execute(`
      SELECT id, page_key, page_name, page_path, category, is_admin_only,
             COALESCE(icon, '') AS icon
      FROM pages
      ORDER BY display_order, page_name
    `);

    if (isAdmin) {
      const adminPages = allPages.filter(p => p.is_admin_only);
      const normalPages = allPages.filter(p => !p.is_admin_only);
      return {
        department_pages: normalPages.map(formatPage),
        personal_pages: [],
        admin_pages: adminPages.map(formatPage)
      };
    }

    // 부서 권한 페이지
    let deptPageIds = new Set();
    if (departmentId) {
      const [deptRows] = await db.execute(`
        SELECT dpp.page_id
        FROM department_page_permissions dpp
        WHERE dpp.department_id = ? AND dpp.can_access = 1
      `, [departmentId]);
      deptRows.forEach(r => deptPageIds.add(r.page_id));
    }

    // 개인 권한 페이지
    const [personalRows] = await db.execute(`
      SELECT upa.page_id
      FROM user_page_access upa
      WHERE upa.user_id = ? AND upa.can_access = 1
    `, [userId]);
    const personalPageIds = new Set(personalRows.map(r => r.page_id));

    // 기본 접근 페이지
    const defaultPages = allPages.filter(p => !p.is_admin_only);

    // 분류
    const departmentPages = [];
    const personalPages = [];

    for (const page of allPages) {
      if (page.is_admin_only) continue;

      if (deptPageIds.has(page.id)) {
        departmentPages.push(formatPage(page));
      } else if (personalPageIds.has(page.id)) {
        personalPages.push(formatPage(page));
      }
    }

    // 기본 접근 페이지 중 부서/개인에 없는 것 추가
    const addedIds = new Set([...departmentPages.map(p => p.page_key), ...personalPages.map(p => p.page_key)]);
    for (const page of defaultPages) {
      if (!addedIds.has(page.page_key) && !page.is_admin_only) {
        departmentPages.push(formatPage(page));
      }
    }

    return {
      department_pages: departmentPages,
      personal_pages: personalPages,
      admin_pages: []
    };
  }
};

function formatPage(page) {
  return {
    page_key: page.page_key,
    page_name: page.page_name,
    page_path: page.page_path,
    icon: page.icon || '',
    category: page.category || ''
  };
}

module.exports = DashboardModel;
