package com.owrawww.migration;

import com.owrawww.util.AesUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 기존 평문 phone/email 데이터를 일괄 암호화하는 마이그레이션 Runner.
 *
 * 실행 방법 (운영 서버):
 *   java -jar owrawww.jar --spring.profiles.active=prod,migration
 *
 * 주의사항:
 *   - 한 번만 실행해야 합니다. 재실행 시 이미 암호화된 데이터는 자동으로 건너뜁니다.
 *   - 실행 전 DB 백업을 반드시 수행하세요.
 *   - 마이그레이션 완료 후 이 profile 없이 앱을 재시작하세요.
 */
@Slf4j
@Profile("migration")
@Component
@RequiredArgsConstructor
public class DataMigrationRunner implements ApplicationRunner {

    private final DataMigrationMapper migrationMapper;
    private final AesUtil             aesUtil;

    @Override
    @Transactional
    public void run(ApplicationArguments args) {
        log.info("=== [마이그레이션 시작] phone/email 암호화 ===");

        List<Map<String, Object>> records = migrationMapper.selectPlainRecords();
        log.info("암호화 대상 레코드 수: {}건", records.size());

        if (records.isEmpty()) {
            log.info("암호화할 평문 데이터가 없습니다. 이미 완료됐거나 데이터가 없습니다.");
            return;
        }

        int success = 0;
        int skip    = 0;

        for (Map<String, Object> row : records) {
            Long   id    = ((Number) row.get("id")).longValue();
            String phone = (String) row.get("phone");
            String email = (String) row.get("email");

            // null/빈값 방어
            if (phone == null || phone.isBlank() || email == null || email.isBlank()) {
                log.warn("  ID={} : phone 또는 email 이 비어있어 건너뜁니다.", id);
                skip++;
                continue;
            }

            try {
                String encPhone   = aesUtil.encrypt(phone);
                String hashPhone  = aesUtil.hash(phone);
                String encEmail   = aesUtil.encrypt(email);
                String hashEmail  = aesUtil.hash(email);

                migrationMapper.updateEncrypted(id, encPhone, hashPhone, encEmail, hashEmail);
                log.info("  ID={} : 암호화 완료", id);
                success++;
            } catch (Exception e) {
                log.error("  ID={} : 암호화 실패 - {}", id, e.getMessage());
                throw new RuntimeException("ID=" + id + " 처리 중 오류 발생. 트랜잭션 롤백.", e);
            }
        }

        log.info("=== [마이그레이션 완료] 성공: {}건, 건너뜀: {}건 ===", success, skip);
        log.info("마이그레이션이 끝났습니다. 'migration' 프로파일 없이 앱을 재시작하세요.");
    }
}
