/**
 * 마이그레이션: 작업 중 문제 신고 시스템
 * - 신고 카테고리 테이블 (부적합/안전)
 * - 사전 정의 신고 항목 테이블
 * - 문제 신고 메인 테이블
 * - 상태 변경 이력 테이블
 */

exports.up = async function(knex) {
  // 1. 신고 카테고리 테이블 생성
  await knex.schema.createTable('issue_report_categories', function(table) {
    table.increments('category_id').primary().comment('카테고리 ID');
    table.enum('category_type', ['nonconformity', 'safety']).notNullable().comment('카테고리 유형 (부적합/안전)');
    table.string('category_name', 100).notNullable().comment('카테고리명');
    table.text('description').nullable().comment('카테고리 설명');
    table.integer('display_order').defaultTo(0).comment('표시 순서');
    table.boolean('is_active').defaultTo(true).comment('활성 여부');
    table.timestamp('created_at').defaultTo(knex.fn.now());

    table.index('category_type', 'idx_irc_category_type');
    table.index('is_active', 'idx_irc_is_active');
  });

  // 카테고리 초기 데이터 삽입
  await knex('issue_report_categories').insert([
    // 부적합 사항
    { category_type: 'nonconformity', category_name: '자재누락', display_order: 1, is_active: true },
    { category_type: 'nonconformity', category_name: '설계미스', display_order: 2, is_active: true },
    { category_type: 'nonconformity', category_name: '입고불량', display_order: 3, is_active: true },
    { category_type: 'nonconformity', category_name: '검사미스', display_order: 4, is_active: true },
    { category_type: 'nonconformity', category_name: '기타 부적합', display_order: 99, is_active: true },
    // 안전 관련
    { category_type: 'safety', category_name: '보호구 미착용', display_order: 1, is_active: true },
    { category_type: 'safety', category_name: '위험구역 출입', display_order: 2, is_active: true },
    { category_type: 'safety', category_name: '안전시설 파손', display_order: 3, is_active: true },
    { category_type: 'safety', category_name: '안전수칙 위반', display_order: 4, is_active: true },
    { category_type: 'safety', category_name: '기타 안전', display_order: 99, is_active: true }
  ]);

  // 2. 사전 정의 신고 항목 테이블 생성
  await knex.schema.createTable('issue_report_items', function(table) {
    table.increments('item_id').primary().comment('항목 ID');
    table.integer('category_id').unsigned().notNullable().comment('소속 카테고리 ID');
    table.string('item_name', 200).notNullable().comment('신고 항목명');
    table.text('description').nullable().comment('항목 설명');
    table.enum('severity', ['low', 'medium', 'high', 'critical']).defaultTo('medium').comment('심각도');
    table.integer('display_order').defaultTo(0).comment('표시 순서');
    table.boolean('is_active').defaultTo(true).comment('활성 여부');
    table.timestamp('created_at').defaultTo(knex.fn.now());

    table.foreign('category_id')
      .references('category_id')
      .inTable('issue_report_categories')
      .onDelete('CASCADE')
      .onUpdate('CASCADE');

    table.index('category_id', 'idx_iri_category_id');
    table.index('is_active', 'idx_iri_is_active');
  });

  // 사전 정의 항목 초기 데이터 삽입
  await knex('issue_report_items').insert([
    // 자재누락 (category_id: 1)
    { category_id: 1, item_name: '배관 자재 미입고', severity: 'high', display_order: 1 },
    { category_id: 1, item_name: '피팅류 부족', severity: 'medium', display_order: 2 },
    { category_id: 1, item_name: '밸브류 미입고', severity: 'high', display_order: 3 },
    { category_id: 1, item_name: '가스켓/볼트류 부족', severity: 'low', display_order: 4 },
    { category_id: 1, item_name: '서포트 자재 부족', severity: 'medium', display_order: 5 },

    // 설계미스 (category_id: 2)
    { category_id: 2, item_name: '도면 치수 오류', severity: 'high', display_order: 1 },
    { category_id: 2, item_name: '스펙 불일치', severity: 'high', display_order: 2 },
    { category_id: 2, item_name: '누락된 상세도', severity: 'medium', display_order: 3 },
    { category_id: 2, item_name: '간섭 발생', severity: 'critical', display_order: 4 },

    // 입고불량 (category_id: 3)
    { category_id: 3, item_name: '외관 불량', severity: 'medium', display_order: 1 },
    { category_id: 3, item_name: '치수 불량', severity: 'high', display_order: 2 },
    { category_id: 3, item_name: '수량 부족', severity: 'medium', display_order: 3 },
    { category_id: 3, item_name: '재질 불일치', severity: 'critical', display_order: 4 },

    // 검사미스 (category_id: 4)
    { category_id: 4, item_name: '치수 검사 누락', severity: 'high', display_order: 1 },
    { category_id: 4, item_name: '외관 검사 누락', severity: 'medium', display_order: 2 },
    { category_id: 4, item_name: '용접 검사 누락', severity: 'critical', display_order: 3 },
    { category_id: 4, item_name: '도장 검사 누락', severity: 'medium', display_order: 4 },

    // 보호구 미착용 (category_id: 6)
    { category_id: 6, item_name: '안전모 미착용', severity: 'high', display_order: 1 },
    { category_id: 6, item_name: '안전화 미착용', severity: 'high', display_order: 2 },
    { category_id: 6, item_name: '보안경 미착용', severity: 'medium', display_order: 3 },
    { category_id: 6, item_name: '안전대 미착용', severity: 'critical', display_order: 4 },
    { category_id: 6, item_name: '귀마개 미착용', severity: 'low', display_order: 5 },
    { category_id: 6, item_name: '안전장갑 미착용', severity: 'medium', display_order: 6 },

    // 위험구역 출입 (category_id: 7)
    { category_id: 7, item_name: '통제구역 무단 출입', severity: 'critical', display_order: 1 },
    { category_id: 7, item_name: '고소 작업 구역 무단 출입', severity: 'critical', display_order: 2 },
    { category_id: 7, item_name: '밀폐공간 무단 진입', severity: 'critical', display_order: 3 },
    { category_id: 7, item_name: '장비 가동 구역 무단 접근', severity: 'high', display_order: 4 },

    // 안전시설 파손 (category_id: 8)
    { category_id: 8, item_name: '안전난간 파손', severity: 'high', display_order: 1 },
    { category_id: 8, item_name: '경고 표지판 훼손', severity: 'medium', display_order: 2 },
    { category_id: 8, item_name: '안전망 파손', severity: 'high', display_order: 3 },
    { category_id: 8, item_name: '비상조명 고장', severity: 'medium', display_order: 4 },
    { category_id: 8, item_name: '소화설비 파손', severity: 'critical', display_order: 5 },

    // 안전수칙 위반 (category_id: 9)
    { category_id: 9, item_name: '지정 통로 미사용', severity: 'medium', display_order: 1 },
    { category_id: 9, item_name: '고소 작업 안전 미준수', severity: 'critical', display_order: 2 },
    { category_id: 9, item_name: '화기 작업 절차 미준수', severity: 'critical', display_order: 3 },
    { category_id: 9, item_name: '정리정돈 미흡', severity: 'low', display_order: 4 },
    { category_id: 9, item_name: '장비 조작 절차 미준수', severity: 'high', display_order: 5 }
  ]);

  // 3. 문제 신고 메인 테이블 생성
  await knex.schema.createTable('work_issue_reports', function(table) {
    table.increments('report_id').primary().comment('신고 ID');

    // 신고자 정보
    table.integer('reporter_id').notNullable().comment('신고자 user_id');
    table.datetime('report_date').defaultTo(knex.fn.now()).comment('신고 일시');

    // 위치 정보
    table.integer('factory_category_id').unsigned().nullable().comment('공장 카테고리 ID (지도 외 위치 시 null)');
    table.integer('workplace_id').unsigned().nullable().comment('작업장 ID (지도 외 위치 시 null)');
    table.string('custom_location', 200).nullable().comment('기타 위치 (지도 외 선택 시)');

    // 작업 연결 정보 (선택적)
    table.integer('tbm_session_id').unsigned().nullable().comment('연결된 TBM 세션');
    table.integer('visit_request_id').unsigned().nullable().comment('연결된 출입 신청');

    // 신고 내용
    table.integer('issue_category_id').unsigned().notNullable().comment('신고 카테고리 ID');
    table.integer('issue_item_id').unsigned().nullable().comment('사전 정의 신고 항목 ID');
    table.text('additional_description').nullable().comment('추가 설명');

    // 사진 (최대 5장)
    table.string('photo_path1', 255).nullable().comment('사진 1');
    table.string('photo_path2', 255).nullable().comment('사진 2');
    table.string('photo_path3', 255).nullable().comment('사진 3');
    table.string('photo_path4', 255).nullable().comment('사진 4');
    table.string('photo_path5', 255).nullable().comment('사진 5');

    // 상태 관리
    table.enum('status', ['reported', 'received', 'in_progress', 'completed', 'closed'])
      .defaultTo('reported')
      .comment('상태: 신고→접수→처리중→완료→종료');

    // 담당자 배정
    table.string('assigned_department', 100).nullable().comment('담당 부서');
    table.integer('assigned_user_id').nullable().comment('담당자 user_id');
    table.datetime('assigned_at').nullable().comment('배정 일시');
    table.integer('assigned_by').nullable().comment('배정자 user_id');

    // 처리 정보
    table.text('resolution_notes').nullable().comment('처리 내용');
    table.string('resolution_photo_path1', 255).nullable().comment('처리 완료 사진 1');
    table.string('resolution_photo_path2', 255).nullable().comment('처리 완료 사진 2');
    table.datetime('resolved_at').nullable().comment('처리 완료 일시');
    table.integer('resolved_by').nullable().comment('처리 완료자 user_id');

    // 수정 이력 (JSON)
    table.json('modification_history').nullable().comment('수정 이력 추적');

    // 타임스탬프
    table.timestamp('created_at').defaultTo(knex.fn.now());
    table.timestamp('updated_at').defaultTo(knex.fn.now());

    // 외래키
    table.foreign('reporter_id')
      .references('user_id')
      .inTable('users')
      .onDelete('RESTRICT')
      .onUpdate('CASCADE');

    table.foreign('factory_category_id')
      .references('category_id')
      .inTable('workplace_categories')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    table.foreign('workplace_id')
      .references('workplace_id')
      .inTable('workplaces')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    table.foreign('issue_category_id')
      .references('category_id')
      .inTable('issue_report_categories')
      .onDelete('RESTRICT')
      .onUpdate('CASCADE');

    table.foreign('issue_item_id')
      .references('item_id')
      .inTable('issue_report_items')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    table.foreign('assigned_user_id')
      .references('user_id')
      .inTable('users')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    table.foreign('assigned_by')
      .references('user_id')
      .inTable('users')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    table.foreign('resolved_by')
      .references('user_id')
      .inTable('users')
      .onDelete('SET NULL')
      .onUpdate('CASCADE');

    // 인덱스
    table.index('reporter_id', 'idx_wir_reporter_id');
    table.index('status', 'idx_wir_status');
    table.index('report_date', 'idx_wir_report_date');
    table.index(['factory_category_id', 'workplace_id'], 'idx_wir_workplace');
    table.index('issue_category_id', 'idx_wir_issue_category');
    table.index('assigned_user_id', 'idx_wir_assigned_user');
  });

  // 4. 상태 변경 이력 테이블 생성
  await knex.schema.createTable('work_issue_status_logs', function(table) {
    table.increments('log_id').primary().comment('로그 ID');
    table.integer('report_id').unsigned().notNullable().comment('신고 ID');
    table.string('previous_status', 50).nullable().comment('이전 상태');
    table.string('new_status', 50).notNullable().comment('새 상태');
    table.integer('changed_by').notNullable().comment('변경자 user_id');
    table.text('change_reason').nullable().comment('변경 사유');
    table.timestamp('changed_at').defaultTo(knex.fn.now());

    table.foreign('report_id')
      .references('report_id')
      .inTable('work_issue_reports')
      .onDelete('CASCADE')
      .onUpdate('CASCADE');

    table.foreign('changed_by')
      .references('user_id')
      .inTable('users')
      .onDelete('RESTRICT')
      .onUpdate('CASCADE');

    table.index('report_id', 'idx_wisl_report_id');
    table.index('changed_at', 'idx_wisl_changed_at');
  });

  console.log('작업 중 문제 신고 시스템 테이블 생성 완료');
};

exports.down = async function(knex) {
  // 역순으로 테이블 삭제
  await knex.schema.dropTableIfExists('work_issue_status_logs');
  await knex.schema.dropTableIfExists('work_issue_reports');
  await knex.schema.dropTableIfExists('issue_report_items');
  await knex.schema.dropTableIfExists('issue_report_categories');

  console.log('작업 중 문제 신고 시스템 테이블 삭제 완료');
};
