/**
 * Permission Model
 *
 * MariaDB user_page_permissions 테이블 CRUD
 */

const { getPool } = require('./userModel');

// 기본 페이지 목록 (시스템별 구분)
const DEFAULT_PAGES = {
  // ===== System 1 - 공장관리 =====
  // 작업 관리
  's1.dashboard':                { title: '대시보드', system: 'system1', group: '작업 관리', default_access: true },
  's1.work.tbm':                 { title: 'TBM 관리', system: 'system1', group: '작업 관리', default_access: true },
  's1.work.report_create':       { title: '작업보고서 작성', system: 'system1', group: '작업 관리', default_access: true },
  's1.work.analysis':            { title: '작업 분석', system: 'system1', group: '작업 관리', default_access: false },
  's1.work.nonconformity':       { title: '부적합 현황', system: 'system1', group: '작업 관리', default_access: true },
  's1.work.schedule':            { title: '공정표', system: 'system1', group: '작업 관리', default_access: false },
  's1.work.meetings':            { title: '생산회의록', system: 'system1', group: '작업 관리', default_access: false },
  's1.work.daily_status':        { title: '입력 현황', system: 'system1', group: '작업 관리', default_access: false },
  's1.work.proxy_input':         { title: '대리입력', system: 'system1', group: '작업 관리', default_access: false },
  // 공장 관리
  's1.factory.repair_management':{ title: '시설설비 관리', system: 'system1', group: '공장 관리', default_access: false },
  's1.inspection.daily_patrol':  { title: '일일순회점검', system: 'system1', group: '공장 관리', default_access: false },
  's1.inspection.checkin':       { title: '출근 체크', system: 'system1', group: '공장 관리', default_access: true },
  's1.inspection.work_status':   { title: '근무 현황', system: 'system1', group: '공장 관리', default_access: false },
  // 소모품 관리
  's1.purchase.request':         { title: '소모품 신청', system: 'system1', group: '소모품 관리', default_access: false },
  's1.purchase.analysis':        { title: '소모품 분석', system: 'system1', group: '소모품 관리', default_access: false },
  's1.attendance.monthly':             { title: '월간 근태', system: 'system1', group: '근태 관리', default_access: true },
  's1.attendance.my_vacation_info':    { title: '내 연차 정보', system: 'system1', group: '근태 관리', default_access: true },
  's1.attendance.vacation_request':    { title: '휴가 신청', system: 'system1', group: '근태 관리', default_access: true },
  's1.attendance.vacation_management': { title: '휴가 관리', system: 'system1', group: '근태 관리', default_access: false },
  's1.attendance.vacation_allocation': { title: '휴가 발생 입력', system: 'system1', group: '근태 관리', default_access: false },
  's1.attendance.annual_overview':     { title: '연간 휴가 현황', system: 'system1', group: '근태 관리', default_access: false },
  's1.attendance.monthly_comparison':  { title: '월간 비교·확인', system: 'system1', group: '근태 관리', default_access: false },
  // 시스템 관리
  's1.admin.workers':            { title: '작업자 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.projects':           { title: '프로젝트 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.tasks':              { title: '작업 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.workplaces':         { title: '작업장 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.equipments':         { title: '설비 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.issue_categories':   { title: '신고 카테고리 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.attendance_report':  { title: '출퇴근-보고서 대조', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.departments':        { title: '부서 관리', system: 'system1', group: '시스템 관리', default_access: false },
  's1.admin.notifications':      { title: '알림 관리', system: 'system1', group: '시스템 관리', default_access: false },
  // 관리
  'factory_proxy_input':         { title: '대리입력',           system: 'system1', group: '관리', default_access: false },
  'factory_daily_status':        { title: '일별 현황',          system: 'system1', group: '관리', default_access: false },
  'factory_tbm':                 { title: 'TBM 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_work_report':         { title: '작업보고서',         system: 'system1', group: '관리', default_access: false },
  'factory_projects':            { title: '프로젝트 관리',      system: 'system1', group: '관리', default_access: false },
  'factory_work_issues':         { title: '업무 이슈',          system: 'system1', group: '관리', default_access: false },
  'factory_purchases':           { title: '구매 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_schedules':           { title: '일정 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_settlements':         { title: '정산 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_meetings':            { title: '회의 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_departments':         { title: '부서 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_tools':               { title: '도구 관리',          system: 'system1', group: '관리', default_access: false },
  'factory_uploads':             { title: '업로드 관리',        system: 'system1', group: '관리', default_access: false },
  'factory_work_analysis':       { title: '공수 분석',          system: 'system1', group: '관리', default_access: false },
  'factory_system':              { title: '시스템 관리',        system: 'system1', group: '시스템 관리', default_access: false },
  // system2 report
  'report_work_issues':          { title: '업무 이슈',          system: 'system2', group: '관리', default_access: false },
  // tkpurchase
  'purchase_schedules':          { title: '작업일정',            system: 'tkpurchase', group: '관리', default_access: false },

  // ===== System 3 - 부적합관리 =====
  // 메인
  'issues_dashboard':   { title: '현황판', system: 'system3', group: '메인', default_access: true },
  'issues_inbox':       { title: '수신함', system: 'system3', group: '메인', default_access: true },
  'issues_management':  { title: '관리함', system: 'system3', group: '메인', default_access: false },
  'issues_archive':     { title: '폐기함', system: 'system3', group: '메인', default_access: false },
  // 보고서
  'reports':            { title: '보고서', system: 'system3', group: '보고서', default_access: false },
  'reports_daily':      { title: '일일보고서', system: 'system3', group: '보고서', default_access: false },
  'reports_weekly':     { title: '주간보고서', system: 'system3', group: '보고서', default_access: false },
  'reports_monthly':    { title: '월간보고서', system: 'system3', group: '보고서', default_access: false },
  // 업무
  'daily_work':         { title: '일일 공수',       system: 'system3', group: '업무', default_access: false },
  'projects_manage':    { title: '프로젝트 관리',   system: 'system3', group: '업무', default_access: false },
  // AI
  'ai_assistant':       { title: 'AI 어시스턴트', system: 'system3', group: 'AI', default_access: false },

  // ===== tkpurchase - 구매 관리 =====
  'purchasing_daylabor':        { title: '일용공 관리',       system: 'tkpurchase', group: '구매 관리', default_access: false },
  'purchasing_schedule':        { title: '작업일정 관리',     system: 'tkpurchase', group: '구매 관리', default_access: false },
  'purchasing_workreport':      { title: '업무현황 관리',     system: 'tkpurchase', group: '구매 관리', default_access: false },
  'purchasing_accounts':        { title: '협력업체 계정',     system: 'tkpurchase', group: '구매 관리', default_access: false },
  'purchasing_partner_portal':  { title: '협력업체 포털',     system: 'tkpurchase', group: '협력업체', default_access: false },
  'purchasing_partner_checkin': { title: '협력업체 체크인',   system: 'tkpurchase', group: '협력업체', default_access: false },

  // ===== tksafety - 안전 관리 =====
  // 출입 관리
  'safety_visit':              { title: '방문 관리',       system: 'tksafety', group: '출입 관리', default_access: true },
  'safety_visit_request':      { title: '출입 신청',       system: 'tksafety', group: '출입 관리', default_access: true },
  'safety_visit_management':   { title: '출입 승인',       system: 'tksafety', group: '출입 관리', default_access: false },
  'safety_entry_dashboard':    { title: '출입 현황판',     system: 'tksafety', group: '출입 관리', default_access: false },
  // 교육/점검
  'safety_education':          { title: '안전교육',         system: 'tksafety', group: '교육/점검', default_access: true },
  'safety_training':           { title: '안전교육 실시',   system: 'tksafety', group: '교육/점검', default_access: false },
  'safety_risk_assessment':    { title: '위험성평가',       system: 'tksafety', group: '교육/점검', default_access: false },
  'safety_checklist':          { title: '체크리스트 관리', system: 'tksafety', group: '교육/점검', default_access: false },

  // ===== tksupport - 행정 지원 =====
  // 일반
  'support_dashboard':          { title: '대시보드',       system: 'tksupport', group: '일반', default_access: true },
  'support_vacation_request':   { title: '휴가 신청',     system: 'tksupport', group: '일반', default_access: true },
  'support_vacation_status':    { title: '내 휴가 현황',  system: 'tksupport', group: '일반', default_access: true },
  // 관리
  'support_vacation_approval':  { title: '휴가 승인',       system: 'tksupport', group: '관리', default_access: false },
  'support_company_holidays':   { title: '전사 휴가 관리',  system: 'tksupport', group: '관리', default_access: false },
  'support_vacation_dashboard': { title: '전체 휴가관리',   system: 'tksupport', group: '관리', default_access: false },
  'support_vacation_admin':     { title: '휴가 보정',       system: 'tksupport', group: '관리', default_access: false },

  // ===== tkuser - 통합 관리 =====
  'tkuser.users':                    { title: '사용자 관리',       system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.projects':                 { title: '프로젝트 관리',     system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.workplaces':               { title: '작업장 관리',       system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.workers':                  { title: '작업자 관리',       system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.departments':              { title: '부서 관리',         system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.issue_types':              { title: '이슈 유형 관리',    system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.tasks':                    { title: '작업 관리',         system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.vacations':                { title: '휴가 관리',         system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.vacation_settings':        { title: '연차 설정',         system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.partners':                 { title: '협력업체 관리',     system: 'tkuser', group: '통합 관리', default_access: false },
  'tkuser.notification_recipients':  { title: '알림 수신자 관리',  system: 'tkuser', group: '통합 관리', default_access: false },
};

/**
 * 사용자의 페이지 권한 목록 조회
 */
async function getUserPermissions(userId) {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT * FROM user_page_permissions WHERE user_id = ? ORDER BY page_name',
    [userId]
  );
  return rows;
}

/**
 * 단건 권한 부여/업데이트 (UPSERT)
 */
async function grantPermission({ user_id, page_name, can_access, granted_by_id, notes }) {
  const db = getPool();
  const [result] = await db.query(
    `INSERT INTO user_page_permissions (user_id, page_name, can_access, granted_by_id, notes)
     VALUES (?, ?, ?, ?, ?)
     ON DUPLICATE KEY UPDATE can_access = VALUES(can_access), granted_by_id = VALUES(granted_by_id), notes = VALUES(notes), granted_at = CURRENT_TIMESTAMP`,
    [user_id, page_name, can_access, granted_by_id, notes || null]
  );
  return { id: result.insertId, user_id, page_name, can_access };
}

/**
 * 일괄 권한 부여 (부서 허용 페이지는 스킵 + 기존 중복 레코드 정리)
 */
async function bulkGrant({ user_id, permissions, granted_by_id }) {
  const db = getPool();
  let count = 0;

  // 부서 권한 조회
  const [userRows] = await db.query(
    'SELECT department_id FROM sso_users WHERE user_id = ?', [user_id]
  );
  const deptId = userRows.length > 0 ? userRows[0].department_id : null;

  const deptGranted = {};
  if (deptId) {
    const [deptPerms] = await db.query(
      'SELECT page_name, can_access FROM department_page_permissions WHERE department_id = ?',
      [deptId]
    );
    deptPerms.forEach(p => { if (p.can_access) deptGranted[p.page_name] = true; });
  }

  for (const perm of permissions) {
    if (!DEFAULT_PAGES[perm.page_name]) continue;

    // 부서가 허용한 페이지는 개인 레코드 삭제 (스킵)
    if (deptGranted[perm.page_name]) {
      await db.query(
        'DELETE FROM user_page_permissions WHERE user_id = ? AND page_name = ?',
        [user_id, perm.page_name]
      );
      continue;
    }

    await db.query(
      `INSERT INTO user_page_permissions (user_id, page_name, can_access, granted_by_id)
       VALUES (?, ?, ?, ?)
       ON DUPLICATE KEY UPDATE can_access = VALUES(can_access), granted_by_id = VALUES(granted_by_id), granted_at = CURRENT_TIMESTAMP`,
      [user_id, perm.page_name, perm.can_access, granted_by_id]
    );
    count++;
  }

  return { updated_count: count };
}

/**
 * 접근 권한 확인 (우선순위: 부서 OR 개인 OR 기본값)
 * 부서가 허용하면 무조건 허용 (개인이 해제 불가)
 */
async function checkAccess(userId, pageName) {
  const db = getPool();

  // 1. 부서 권한 (마스터) — 부서가 허용하면 무조건 허용
  const [userRows] = await db.query(
    'SELECT department_id FROM sso_users WHERE user_id = ?', [userId]
  );
  if (userRows.length > 0 && userRows[0].department_id) {
    const [deptRows] = await db.query(
      'SELECT can_access FROM department_page_permissions WHERE department_id = ? AND page_name = ?',
      [userRows[0].department_id, pageName]
    );
    if (deptRows.length > 0 && deptRows[0].can_access) {
      return { can_access: true, reason: 'department_permission' };
    }
  }

  // 2. 개인 권한 (추가 부여)
  const [rows] = await db.query(
    'SELECT can_access FROM user_page_permissions WHERE user_id = ? AND page_name = ?',
    [userId, pageName]
  );
  if (rows.length > 0) {
    return { can_access: rows[0].can_access, reason: 'explicit_permission' };
  }

  // 3. 기본 권한
  const pageConfig = DEFAULT_PAGES[pageName];
  if (!pageConfig) return { can_access: false, reason: 'invalid_page' };
  return { can_access: pageConfig.default_access, reason: 'default_permission' };
}

/**
 * 부서별 페이지 권한 조회
 */
async function getDepartmentPermissions(departmentId) {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT * FROM department_page_permissions WHERE department_id = ? ORDER BY page_name',
    [departmentId]
  );
  return rows;
}

/**
 * 부서 권한 단건 UPSERT
 */
async function setDepartmentPermission({ department_id, page_name, can_access, granted_by_id }) {
  const db = getPool();
  const [result] = await db.query(
    `INSERT INTO department_page_permissions (department_id, page_name, can_access, granted_by_id)
     VALUES (?, ?, ?, ?)
     ON DUPLICATE KEY UPDATE can_access = VALUES(can_access), granted_by_id = VALUES(granted_by_id), granted_at = CURRENT_TIMESTAMP`,
    [department_id, page_name, can_access, granted_by_id]
  );
  return { id: result.insertId, department_id, page_name, can_access };
}

/**
 * 부서 권한 일괄 설정
 */
async function bulkSetDepartmentPermissions({ department_id, permissions, granted_by_id }) {
  const db = getPool();
  let count = 0;

  for (const perm of permissions) {
    if (!DEFAULT_PAGES[perm.page_name]) continue;
    await db.query(
      `INSERT INTO department_page_permissions (department_id, page_name, can_access, granted_by_id)
       VALUES (?, ?, ?, ?)
       ON DUPLICATE KEY UPDATE can_access = VALUES(can_access), granted_by_id = VALUES(granted_by_id), granted_at = CURRENT_TIMESTAMP`,
      [department_id, perm.page_name, perm.can_access, granted_by_id]
    );
    count++;
  }

  return { updated_count: count };
}

/**
 * 부서 권한 삭제 (기본값으로 복귀)
 */
async function deleteDepartmentPermission(departmentId, pageName) {
  const db = getPool();
  const [result] = await db.query(
    'DELETE FROM department_page_permissions WHERE department_id = ? AND page_name = ?',
    [departmentId, pageName]
  );
  return result.affectedRows > 0;
}

/**
 * 사용자 권한 + 출처 조회 (각 페이지별 현재 적용 권한과 출처 반환)
 */
async function getUserPermissionsWithSource(userId) {
  const db = getPool();

  // 개인 권한 조회
  const [userPerms] = await db.query(
    'SELECT page_name, can_access FROM user_page_permissions WHERE user_id = ?',
    [userId]
  );
  const userPermMap = {};
  userPerms.forEach(p => { userPermMap[p.page_name] = !!p.can_access; });

  // 부서 권한 조회
  const [userRows] = await db.query(
    'SELECT department_id FROM sso_users WHERE user_id = ?',
    [userId]
  );
  const deptId = userRows.length > 0 ? userRows[0].department_id : null;

  const deptPermMap = {};
  if (deptId) {
    const [deptPerms] = await db.query(
      'SELECT page_name, can_access FROM department_page_permissions WHERE department_id = ?',
      [deptId]
    );
    deptPerms.forEach(p => { deptPermMap[p.page_name] = !!p.can_access; });
  }

  // 모든 페이지에 대해 결과 조합 (부서 OR 개인 OR 기본)
  const result = {};
  for (const [pageName, config] of Object.entries(DEFAULT_PAGES)) {
    const deptGranted = deptPermMap[pageName] === true;

    if (deptGranted) {
      // 부서가 허용 → 무조건 허용, 잠금
      result[pageName] = { can_access: true, source: 'department', dept_granted: true };
    } else if (pageName in userPermMap) {
      result[pageName] = { can_access: userPermMap[pageName], source: 'explicit', dept_granted: false };
    } else {
      result[pageName] = { can_access: config.default_access, source: 'default', dept_granted: false };
    }
  }

  return { permissions: result, department_id: deptId };
}

/**
 * 부서 이동 시 개인 권한 초기화 — user_page_permissions 전체 삭제
 */
async function clearUserPermissionsForDepartmentChange(userId) {
  const db = getPool();
  const [result] = await db.query(
    'DELETE FROM user_page_permissions WHERE user_id = ?',
    [userId]
  );
  return { deleted_count: result.affectedRows };
}

/**
 * 권한 삭제 (기본값으로 되돌림)
 */
async function deletePermission(permissionId) {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT * FROM user_page_permissions WHERE id = ?',
    [permissionId]
  );
  if (rows.length === 0) return null;

  await db.query('DELETE FROM user_page_permissions WHERE id = ?', [permissionId]);
  return rows[0];
}

module.exports = {
  DEFAULT_PAGES,
  getUserPermissions,
  grantPermission,
  bulkGrant,
  checkAccess,
  deletePermission,
  getDepartmentPermissions,
  setDepartmentPermission,
  bulkSetDepartmentPermissions,
  deleteDepartmentPermission,
  getUserPermissionsWithSource,
  clearUserPermissionsForDepartmentChange
};
