#!/usr/bin/env python3
"""
사용자 비밀번호 마이그레이션 스크립트
mlinkdw.userinf 테이블의 USERPWD를 werkzeug의 generate_password_hash()로 암호화하여
mlink_db.user 테이블에 삽입합니다.
"""

import os
import sys
from datetime import datetime

# 프로젝트 루트 경로 추가
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from werkzeug.security import generate_password_hash
from sqlalchemy import create_engine, text
from dotenv import load_dotenv
import logging

# 로깅 설정
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)

# 환경 변수 로드
load_dotenv()

def get_database_url():
    """데이터베이스 URL 가져오기"""
    # 기존 데이터베이스 (mlinkdw)
    source_db_url = os.getenv('SOURCE_DATABASE_URL', 'mysql+pymysql://mlink_user:1111@dw.kdjsystem.com:3306/mlinkdw')
    # 대상 데이터베이스 (mlink_db)
    target_db_url = os.getenv('DATABASE_URL', 'mysql+pymysql://mlink_user:1111@dw.kdjsystem.com:3306/mlink_db')
    return source_db_url, target_db_url

def migrate_user_passwords():
    """사용자 비밀번호 마이그레이션"""
    source_db_url, target_db_url = get_database_url()
    
    # 데이터베이스 연결
    source_engine = create_engine(source_db_url)
    target_engine = create_engine(target_db_url)
    
    try:
        # 소스 데이터베이스에서 사용자 정보 조회
        query = text("""
            SELECT USERID, USERNAM, USERPWD, STARTUSE, ENDUSE, PRICETYPE
            FROM userinf 
            WHERE PRICETYPE <> 0 
              AND ENDUSE >= '2025-11-12' 
              AND ENDUSE < '9999-12-31 23:11:59'
        """)
        
        logger.info("소스 데이터베이스에서 사용자 정보 조회 중...")
        with source_engine.connect() as source_conn:
            result = source_conn.execute(query)
            users = result.fetchall()
        
        logger.info(f"총 {len(users)}명의 사용자 정보를 찾았습니다.")
        
        # 대상 데이터베이스에 삽입
        success_count = 0
        error_count = 0
        
        with target_engine.connect() as target_conn:
            for user in users:
                try:
                    userid = user[0]  # USERID
                    username = user[1]  # USERNAM
                    userpwd = user[2]  # USERPWD (평문)
                    startuse = user[3]  # STARTUSE
                    enduse = user[4]  # ENDUSE
                    pricetype = user[5]  # PRICETYPE
                    
                    # 비밀번호 암호화
                    if userpwd:
                        password_hash = generate_password_hash(userpwd)
                    else:
                        # 비밀번호가 없는 경우 기본값 설정 (실제로는 사용자가 재설정해야 함)
                        password_hash = generate_password_hash('temp_password_123')
                        logger.warning(f"사용자 {userid}의 비밀번호가 없어 임시 비밀번호를 설정했습니다.")
                    
                    # subscription_type 결정 (PRICETYPE에 따라)
                    # PRICETYPE이 0이 아니므로 'monthly'로 설정 (Enum 값)
                    subscription_type = 'monthly'
                    
                    # 중복 체크 (이미 존재하는 사용자는 건너뛰기)
                    check_query = text("SELECT id FROM user WHERE email = :email")
                    existing = target_conn.execute(check_query, {"email": userid}).fetchone()
                    
                    if existing:
                        logger.info(f"사용자 {userid}는 이미 존재합니다. 건너뜁니다.")
                        continue
                    
                    # INSERT 쿼리 실행
                    insert_query = text("""
                        INSERT INTO user (
                            email, 
                            username, 
                            password_hash, 
                            is_active, 
                            subscription_type, 
                            created_at, 
                            updated_at
                        ) VALUES (
                            :email,
                            :username,
                            :password_hash,
                            :is_active,
                            :subscription_type,
                            :created_at,
                            :updated_at
                        )
                    """)
                    
                    target_conn.execute(insert_query, {
                        "email": userid,
                        "username": username or userid,  # USERNAM이 없으면 USERID 사용
                        "password_hash": password_hash,
                        "is_active": 1,
                        "subscription_type": subscription_type,
                        "created_at": startuse if startuse else datetime.now(),
                        "updated_at": enduse if enduse else datetime.now()
                    })
                    
                    target_conn.commit()
                    success_count += 1
                    
                    if success_count % 100 == 0:
                        logger.info(f"진행 상황: {success_count}명 처리 완료...")
                    
                except Exception as e:
                    error_count += 1
                    logger.error(f"사용자 {userid} 처리 중 오류 발생: {str(e)}")
                    target_conn.rollback()
                    continue
        
        logger.info("=" * 50)
        logger.info(f"마이그레이션 완료!")
        logger.info(f"성공: {success_count}명")
        logger.info(f"실패: {error_count}명")
        logger.info(f"총 처리: {len(users)}명")
        logger.info("=" * 50)
        
    except Exception as e:
        logger.error(f"마이그레이션 중 오류 발생: {str(e)}")
        raise
    finally:
        source_engine.dispose()
        target_engine.dispose()

if __name__ == '__main__':
    logger.info("사용자 비밀번호 마이그레이션 시작...")
    logger.info("주의: 이 스크립트는 기존 데이터베이스의 비밀번호를 암호화하여 새 테이블에 삽입합니다.")
    
    # 확인 메시지
    response = input("계속하시겠습니까? (yes/no): ")
    if response.lower() != 'yes':
        logger.info("마이그레이션이 취소되었습니다.")
        sys.exit(0)
    
    migrate_user_passwords()
    logger.info("마이그레이션이 완료되었습니다.")

