/**
 * 권한 시스템 단순화 및 페이지 접근 권한 추가
 * - Leader와 Worker를 User로 통합
 * - 페이지 접근 권한 테이블 생성
 * - Admin이 사용자별 페이지 접근 권한을 설정할 수 있도록 함
 *
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = async function(knex) {
  // 1. 페이지 목록 테이블 생성
  await knex.schema.createTable('pages', function(table) {
    table.increments('id').primary();
    table.string('page_key', 100).notNullable().unique(); // 예: 'worker-management', 'project-management'
    table.string('page_name', 100).notNullable(); // 예: '작업자 관리', '프로젝트 관리'
    table.string('page_path', 255).notNullable(); // 예: '/pages/management/worker-management.html'
    table.string('category', 50); // 예: 'management', 'dashboard', 'admin'
    table.string('description', 255);
    table.boolean('is_admin_only').defaultTo(false); // Admin 전용 페이지 여부
    table.integer('display_order').defaultTo(0); // 표시 순서
    table.timestamps(true, true);
  });

  // 2. 사용자별 페이지 접근 권한 테이블 생성
  await knex.schema.createTable('user_page_access', function(table) {
    table.integer('user_id').notNullable()
      .references('user_id').inTable('users').onDelete('CASCADE');
    table.integer('page_id').unsigned().notNullable()
      .references('id').inTable('pages').onDelete('CASCADE');
    table.boolean('can_access').defaultTo(true); // 접근 가능 여부
    table.timestamp('granted_at').defaultTo(knex.fn.now());
    table.integer('granted_by') // 권한을 부여한 Admin의 user_id
      .references('user_id').inTable('users').onDelete('SET NULL');
    table.primary(['user_id', 'page_id']);
  });

  // 3. 기본 페이지 목록 삽입
  await knex('pages').insert([
    // Dashboard
    { page_key: 'dashboard-user', page_name: '사용자 대시보드', page_path: '/pages/dashboard/user.html', category: 'dashboard', is_admin_only: false, display_order: 1 },
    { page_key: 'dashboard-leader', page_name: '그룹장 대시보드', page_path: '/pages/dashboard/group-leader.html', category: 'dashboard', is_admin_only: false, display_order: 2 },

    // Management
    { page_key: 'worker-management', page_name: '작업자 관리', page_path: '/pages/management/worker-management.html', category: 'management', is_admin_only: false, display_order: 10 },
    { page_key: 'project-management', page_name: '프로젝트 관리', page_path: '/pages/management/project-management.html', category: 'management', is_admin_only: false, display_order: 11 },
    { page_key: 'work-management', page_name: '작업 관리', page_path: '/pages/management/work-management.html', category: 'management', is_admin_only: false, display_order: 12 },
    { page_key: 'code-management', page_name: '코드 관리', page_path: '/pages/management/code-management.html', category: 'management', is_admin_only: false, display_order: 13 },

    // Common
    { page_key: 'daily-work-report', page_name: '작업 현황 확인', page_path: '/pages/common/daily-work-report-viewer.html', category: 'common', is_admin_only: false, display_order: 20 },

    // Admin
    { page_key: 'user-management', page_name: '사용자 관리', page_path: '/pages/admin/manage-user.html', category: 'admin', is_admin_only: true, display_order: 100 },
  ]);

  // 4. roles 테이블 업데이트: Leader와 Worker를 User로 통합
  // Leader와 Worker 역할을 가진 사용자를 모두 User로 변경
  const userRoleId = await knex('roles').where('name', 'Worker').first().then(r => r.id);
  const leaderRoleId = await knex('roles').where('name', 'Leader').first().then(r => r ? r.id : null);

  if (leaderRoleId) {
    // Leader를 User로 변경
    await knex('users').where('role_id', leaderRoleId).update({ role_id: userRoleId });
  }

  // 5. role_permissions 업데이트: Worker 권한을 확장하여 모든 일반 기능 사용 가능하게
  const allPermissions = await knex('permissions').select('id', 'name');
  const permissionMap = allPermissions.reduce((acc, p) => {
    acc[p.name] = p.id;
    return acc;
  }, {});

  // Worker 역할의 기존 권한 삭제
  await knex('role_permissions').where('role_id', userRoleId).del();

  // Worker(이제 User) 역할에 모든 일반 권한 부여 (Admin/System 권한 제외)
  const userPermissions = [
    permissionMap['user:read'],
    permissionMap['project:read'],
    permissionMap['project:create'],
    permissionMap['project:update'],
    permissionMap['work-report:create'],
    permissionMap['work-report:read-own'],
    permissionMap['work-report:read-team'],
    permissionMap['work-report:read-all'],
    permissionMap['work-report:update'],
    permissionMap['work-report:delete'],
  ].filter(Boolean); // undefined 제거

  const rolePermissionInserts = userPermissions.map(permissionId => ({
    role_id: userRoleId,
    permission_id: permissionId
  }));

  await knex('role_permissions').insert(rolePermissionInserts);

  // 6. Leader 역할 삭제 (더 이상 사용하지 않음)
  if (leaderRoleId) {
    await knex('role_permissions').where('role_id', leaderRoleId).del();
    await knex('roles').where('id', leaderRoleId).del();
  }

  // 7. Worker 역할 이름을 'User'로 변경
  await knex('roles').where('id', userRoleId).update({
    name: 'User',
    description: '일반 사용자. 작업 보고서 및 프로젝트 관리 등 모든 일반 기능을 사용할 수 있음.'
  });

  // 8. 모든 일반 사용자에게 모든 페이지 접근 권한 부여 (Admin 페이지 제외)
  const normalPages = await knex('pages').where('is_admin_only', false).select('id');
  const normalUsers = await knex('users').where('role_id', userRoleId).select('user_id');

  const userPageAccessInserts = [];
  normalUsers.forEach(user => {
    normalPages.forEach(page => {
      userPageAccessInserts.push({
        user_id: user.user_id,
        page_id: page.id,
        can_access: true
      });
    });
  });

  if (userPageAccessInserts.length > 0) {
    await knex('user_page_access').insert(userPageAccessInserts);
  }
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = async function(knex) {
  // 테이블 삭제 (역순)
  await knex.schema.dropTableIfExists('user_page_access');
  await knex.schema.dropTableIfExists('pages');

  // User 역할을 다시 Worker로 변경
  const userRoleId = await knex('roles').where('name', 'User').first().then(r => r ? r.id : null);
  if (userRoleId) {
    await knex('roles').where('id', userRoleId).update({
      name: 'Worker',
      description: '일반 작업자. 자신의 작업 보고서 작성 및 조회 권한.'
    });
  }

  // Leader 역할 재생성
  await knex('roles').insert([
    { id: 3, name: 'Leader', description: '그룹장. 팀원 작업 현황 조회 등 중간 관리자 권한.' }
  ]);
};
