/**
 * worker_id → user_id 통합 마이그레이션 (Phase 1)
 *
 * 비파괴적 추가: 기존 worker_id 컬럼은 유지하면서 user_id 컬럼을 추가하고 백필.
 * 코드 변경 전이므로 기존 시스템 동작에 영향 없음.
 *
 * 대상 테이블:
 *   1. departments - is_production 플래그 추가
 *   2. sso_users - department_id 추가 (없는 경우)
 *   3. workers - user_id 추가 + 매핑 백필
 *   4~15. 12개 참조 테이블 - user_id 추가 + 백필
 *
 * @since 2026-03-05
 */

exports.up = async function(knex) {
  // ============================================================
  // 1. departments 테이블에 is_production 플래그 추가
  // ============================================================
  const hasIsProduction = await knex.schema.hasColumn('departments', 'is_production');
  if (!hasIsProduction) {
    await knex.schema.table('departments', (table) => {
      table.boolean('is_production').defaultTo(false).comment('생산직 부서 여부');
    });
    await knex.raw(`UPDATE departments SET is_production = TRUE WHERE department_name LIKE '%생산%'`);
  }

  // ============================================================
  // 2. sso_users에 department_id 추가 (없는 경우)
  // ============================================================
  const hasSsoDeptId = await knex.schema.hasColumn('sso_users', 'department_id');
  if (!hasSsoDeptId) {
    await knex.schema.table('sso_users', (table) => {
      table.integer('department_id').unsigned().defaultTo(null).comment('소속 부서 ID');
    });
    // 기존 department(문자열) → department_id(FK) 매핑
    await knex.raw(`
      UPDATE sso_users s
      INNER JOIN departments d ON s.department = d.department_name
      SET s.department_id = d.department_id
      WHERE s.department IS NOT NULL
    `);
  }

  // ============================================================
  // 3. workers 테이블에 user_id 추가 + 매핑 백필
  // ============================================================
  const hasWorkersUserId = await knex.schema.hasColumn('workers', 'user_id');
  if (!hasWorkersUserId) {
    await knex.schema.table('workers', (table) => {
      table.integer('user_id').unsigned().defaultTo(null).after('worker_id')
        .comment('sso_users.user_id 매핑');
    });
    // users 테이블을 경유하여 sso_users.user_id 매핑
    await knex.raw(`
      UPDATE workers w
      INNER JOIN users u ON u.worker_id = w.worker_id
      INNER JOIN sso_users s ON s.username = u.username
      SET w.user_id = s.user_id
    `);
    // user_id에 인덱스 추가
    await knex.raw(`ALTER TABLE workers ADD INDEX idx_workers_user_id (user_id)`);
  }

  // ============================================================
  // 4~15. 12개 참조 테이블에 user_id 컬럼 추가 + 백필
  // ============================================================

  // worker_id 컬럼을 가진 테이블들
  const tablesWithWorkerId = [
    'tbm_team_assignments',
    'tbm_transfers',
    'daily_work_reports',
    'daily_attendance_records',
    'worker_vacation_balance',
    'vacation_requests',
    'vacation_balance_details',
    'worker_groups',
    'monthly_worker_status',
  ];

  for (const tableName of tablesWithWorkerId) {
    const tableExists = await knex.schema.hasTable(tableName);
    if (!tableExists) {
      continue;
    }

    const hasUserId = await knex.schema.hasColumn(tableName, 'user_id');
    if (!hasUserId) {
      await knex.schema.table(tableName, (table) => {
        table.integer('user_id').unsigned().defaultTo(null).comment('sso_users.user_id');
      });
      // 백필: workers 테이블의 user_id 매핑 사용
      await knex.raw(`
        UPDATE ${tableName} t
        INNER JOIN workers w ON t.worker_id = w.worker_id
        SET t.user_id = w.user_id
        WHERE w.user_id IS NOT NULL
      `);
      // 인덱스 추가
      await knex.raw(`ALTER TABLE ${tableName} ADD INDEX idx_${tableName}_user_id (user_id)`);
    }
  }

  // DailyIssueReports (대소문자 다른 테이블명)
  const hasDIR = await knex.schema.hasTable('DailyIssueReports');
  if (hasDIR) {
    const hasDIRUserId = await knex.schema.hasColumn('DailyIssueReports', 'user_id');
    if (!hasDIRUserId) {
      await knex.schema.table('DailyIssueReports', (table) => {
        table.integer('user_id').unsigned().defaultTo(null).comment('sso_users.user_id');
      });
      await knex.raw(`
        UPDATE DailyIssueReports t
        INNER JOIN workers w ON t.worker_id = w.worker_id
        SET t.user_id = w.user_id
        WHERE w.user_id IS NOT NULL
      `);
    }
  }

  // WorkReports (대소문자 다른 테이블명)
  const hasWR = await knex.schema.hasTable('WorkReports');
  if (hasWR) {
    const hasWRUserId = await knex.schema.hasColumn('WorkReports', 'user_id');
    if (!hasWRUserId) {
      await knex.schema.table('WorkReports', (table) => {
        table.integer('user_id').unsigned().defaultTo(null).comment('sso_users.user_id');
      });
      await knex.raw(`
        UPDATE WorkReports t
        INNER JOIN workers w ON t.worker_id = w.worker_id
        SET t.user_id = w.user_id
        WHERE w.user_id IS NOT NULL
      `);
    }
  }

  // tbm_sessions: leader_id → leader_user_id 추가
  const hasLeaderUserId = await knex.schema.hasColumn('tbm_sessions', 'leader_user_id');
  if (!hasLeaderUserId) {
    await knex.schema.table('tbm_sessions', (table) => {
      table.integer('leader_user_id').unsigned().defaultTo(null).comment('조장 sso_users.user_id');
    });
    await knex.raw(`
      UPDATE tbm_sessions t
      INNER JOIN workers w ON t.leader_id = w.worker_id
      SET t.leader_user_id = w.user_id
      WHERE w.user_id IS NOT NULL
    `);
    await knex.raw(`ALTER TABLE tbm_sessions ADD INDEX idx_tbm_sessions_leader_user_id (leader_user_id)`);
  }

  // team_handovers: from/to_leader_id → from/to_leader_user_id 추가
  const hasFromLeaderUserId = await knex.schema.hasColumn('team_handovers', 'from_leader_user_id');
  if (!hasFromLeaderUserId) {
    await knex.schema.table('team_handovers', (table) => {
      table.integer('from_leader_user_id').unsigned().defaultTo(null).comment('인계자 sso_users.user_id');
      table.integer('to_leader_user_id').unsigned().defaultTo(null).comment('인수자 sso_users.user_id');
    });
    await knex.raw(`
      UPDATE team_handovers t
      INNER JOIN workers w1 ON t.from_leader_id = w1.worker_id
      SET t.from_leader_user_id = w1.user_id
      WHERE w1.user_id IS NOT NULL
    `);
    await knex.raw(`
      UPDATE team_handovers t
      INNER JOIN workers w2 ON t.to_leader_id = w2.worker_id
      SET t.to_leader_user_id = w2.user_id
      WHERE w2.user_id IS NOT NULL
    `);
  }

};

exports.down = async function(knex) {
  // user_id 컬럼 제거 (롤백)
  const columnsToRemove = [
    ['departments', 'is_production'],
    ['workers', 'user_id'],
    ['tbm_team_assignments', 'user_id'],
    ['tbm_transfers', 'user_id'],
    ['daily_work_reports', 'user_id'],
    ['daily_attendance_records', 'user_id'],
    ['worker_vacation_balance', 'user_id'],
    ['vacation_requests', 'user_id'],
    ['vacation_balance_details', 'user_id'],
    ['worker_groups', 'user_id'],
    ['monthly_worker_status', 'user_id'],
    ['tbm_sessions', 'leader_user_id'],
    ['team_handovers', 'from_leader_user_id'],
    ['team_handovers', 'to_leader_user_id'],
  ];

  for (const [tableName, columnName] of columnsToRemove) {
    const tableExists = await knex.schema.hasTable(tableName);
    if (!tableExists) continue;
    const hasColumn = await knex.schema.hasColumn(tableName, columnName);
    if (hasColumn) {
      await knex.schema.table(tableName, (table) => {
        table.dropColumn(columnName);
      });
    }
  }

  // 대소문자 다른 테이블
  for (const tableName of ['DailyIssueReports', 'WorkReports']) {
    const tableExists = await knex.schema.hasTable(tableName);
    if (tableExists) {
      const hasColumn = await knex.schema.hasColumn(tableName, 'user_id');
      if (hasColumn) {
        await knex.schema.table(tableName, (table) => {
          table.dropColumn('user_id');
        });
      }
    }
  }

  // sso_users.department_id는 유지 (다른 마이그레이션에서 관리)
};
