from flask import Blueprint, jsonify, request, session
from src.models.user import User, db
from src.utils.user_ref import get_user_by_session_value, allocate_unique_user_id_from_email
from src.models.credit import CreditTransaction, CreditBalance
from src.utils.credit_manager import (
    get_or_create_credit_balance,
    renew_daily_credits,
    add_signup_bonus
)
from sqlalchemy import desc

user_bp = Blueprint('user', __name__)

@user_bp.route('/api/auth/check', methods=['GET'])
def check_auth():
    """사용자 인증 상태 확인"""
    try:
        user_id = session.get('user_id')
        if not user_id:
            # 테스트용으로 기본 사용자 정보 반환
            user = User.query.get(1)
            if user:
                return jsonify({
                    'authenticated': True,
                    'user': user.to_dict()
                })
            else:
                return jsonify({
                    'authenticated': False,
                    'user': None
                })
        
        user = get_user_by_session_value(user_id)
        if user:
            return jsonify({
                'authenticated': True,
                'user': user.to_dict()
            })
        else:
            return jsonify({
                'authenticated': False,
                'user': None
            })
    except Exception as e:
        return jsonify({
            'authenticated': False,
            'user': None,
            'error': str(e)
        })

@user_bp.route('/users', methods=['GET'])
def get_users():
    users = User.query.all()
    return jsonify([user.to_dict() for user in users])

@user_bp.route('/users', methods=['POST'])
def create_user():
    
    data = request.json
    uid = allocate_unique_user_id_from_email(data['email'], data.get('username'))
    user = User(user_id=uid, username=data['username'], email=data['email'])
    db.session.add(user)
    db.session.commit()
    return jsonify(user.to_dict()), 201

@user_bp.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get_or_404(user_id)
    return jsonify(user.to_dict())

@user_bp.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    user = User.query.get_or_404(user_id)
    data = request.json
    user.username = data.get('username', user.username)
    user.email = data.get('email', user.email)
    db.session.commit()
    return jsonify(user.to_dict())

@user_bp.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    user = User.query.get_or_404(user_id)
    db.session.delete(user)
    db.session.commit()
    return '', 204

@user_bp.route('/api/user/credits', methods=['GET'])
def get_user_credits():
    """사용자 크레딧 정보 및 거래 내역 조회"""
    try:
        user_id = session.get('user_id')
        if not user_id:
            # 테스트용: PK=1 사용자의 업무 user_id 사용 (없으면 이후 쿼리 실패 가능)
            u1 = User.query.get(1)
            user_id = u1.user_id if u1 else None
            if not user_id:
                return jsonify({'success': False, 'error': '로그인이 필요합니다.'}), 401
        
        # 페이지네이션 파라미터
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        
        # 크레딧 잔액 조회 (없으면 생성)
        credit_balance = get_or_create_credit_balance(user_id)
        
        # 일일 크레딧 갱신 확인 (매일 00:00에 자동 갱신)
        # 주의: 일일 재충전은 자정 KST 잡(job)으로 처리되므로 주석 처리
        # renew_daily_credits(user_id)
        # 갱신 후 다시 조회
        credit_balance = CreditBalance.query.filter_by(user_id=user_id).first()
        
        # 크레딧 거래 내역 조회 (페이지네이션)
        pagination = CreditTransaction.query.filter_by(user_id=user_id)\
            .order_by(desc(CreditTransaction.created_at))\
            .paginate(page=page, per_page=per_page, error_out=False)
        
        transactions = []
        for transaction in pagination.items:
            transactions.append({
                'detail': transaction.description or '',
                'date': transaction.created_at.strftime('%Y-%m-%d %H:%M') if transaction.created_at else '',
                'creditChange': transaction.amount
            })
        
        return jsonify({
            'success': True,
            'totalCredit': credit_balance.total_credit,
            'freeCredit': credit_balance.free_credit,
            'addOnCredit': credit_balance.add_on_credit,
            'dailyRenewalCredit': credit_balance.daily_renewal_credit,
            'eventCredit': credit_balance.event_credit,
            'subscriptionCredit': credit_balance.subscription_credit,
            'history': transactions,
            'totalPages': pagination.pages,
            'currentPage': page,
            'totalItems': pagination.total
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@user_bp.route('/api/user/credits/balance', methods=['GET'])
def get_user_credit_balance():
    """사용자 크레딧 잔액만 조회 (간단한 정보)"""
    try:
        user_id = session.get('user_id')
        if not user_id:
            # 테스트용: PK=1 사용자의 업무 user_id 사용 (없으면 이후 쿼리 실패 가능)
            u1 = User.query.get(1)
            user_id = u1.user_id if u1 else None
            if not user_id:
                return jsonify({'success': False, 'error': '로그인이 필요합니다.'}), 401
        
        # 크레딧 잔액 조회 (없으면 생성)
        credit_balance = get_or_create_credit_balance(user_id)
        
        # 일일 크레딧 갱신 확인 (매일 00:00에 자동 갱신)
        # 주의: 일일 재충전은 자정 KST 잡(job)으로 처리되므로 주석 처리
        # renew_daily_credits(user_id)
        # 갱신 후 다시 조회
        credit_balance = CreditBalance.query.filter_by(user_id=user_id).first()
        
        return jsonify({
            'success': True,
            'totalCredit': credit_balance.total_credit,
            'freeCredit': credit_balance.free_credit,
            'addOnCredit': credit_balance.add_on_credit,
            'dailyRenewalCredit': credit_balance.daily_renewal_credit,
            'eventCredit': credit_balance.event_credit,
            'subscriptionCredit': credit_balance.subscription_credit
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
