"""
Flask 애플리케이션 공통 데코레이터
"""
from functools import wraps
from flask import session, redirect, url_for, jsonify, flash, request
from utils.common import get_db_connection
import jwt
import os
from dotenv import load_dotenv

load_dotenv()
JWT_SECRET = os.getenv("JWT_SECRET", "4f3c2e1a5b6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2")
JWT_ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256")


def login_required(f):
    """로그인 필요 데코레이터 (JWT 토큰도 확인)"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 세션에 로그인 정보가 있으면 통과
        if 'username' in session:
            return f(*args, **kwargs)
        
        # 쿠키에서 JWT 토큰 확인
        token = request.cookies.get('infrasmart_token')
        if token:
            try:
                # JWT 토큰 검증
                decoded = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
                email = decoded.get('email')
                username = decoded.get('username')
                
                if email:
                    # 데이터베이스에서 사용자 정보 확인
                    conn = get_db_connection()
                    cur = conn.cursor()
                    try:
                        cur.execute('SELECT id, username, email FROM users WHERE email = %s', (email,))
                        user = cur.fetchone()
                        
                        if user:
                            # 세션에 사용자 정보 저장
                            # users 테이블 구조: id, username, password, email, ...
                            session['user_id'] = user[0]
                            session['username'] = user[1]
                            session['email'] = user[3] if len(user) > 3 else email
                            return f(*args, **kwargs)
                    finally:
                        cur.close()
                        conn.close()
            except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
                # 토큰이 만료되었거나 유효하지 않음
                pass
            except Exception as e:
                print(f"JWT 토큰 검증 오류: {e}")
        
        # 로그인되지 않았으면 로그인 페이지로 리다이렉트
        # AJAX 요청인 경우 JSON 응답
        if hasattr(f, '__name__') and any(x in f.__name__ for x in ['api_', 'ajax_', 'get_', 'update_']):
            return jsonify({'error': 'Login required'}), 401
        return redirect(url_for('auth.login'))
    return decorated_function


def admin_required(f):
    """관리자 권한 필요 데코레이터"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        from flask import request
        
        if 'user_id' not in session:
            # API 요청인 경우 JSON 응답
            if request.path.startswith('/admin/api/') or request.is_json:
                return jsonify({'error': '로그인이 필요합니다.', 'success': False}), 401
            flash('로그인이 필요합니다.', 'error')
            return redirect(url_for('auth.login'))
        
        # 관리자 권한 확인
        user_id = session.get('user_id')
        conn = get_db_connection()
        cur = conn.cursor()
        
        try:
            cur.execute('SELECT is_admin FROM users WHERE id = %s', (user_id,))
            result = cur.fetchone()
            
            if not result or not result[0]:
                # API 요청인 경우 JSON 응답
                if request.path.startswith('/admin/api/') or request.is_json:
                    return jsonify({'error': '관리자 권한이 필요합니다.', 'success': False}), 403
                flash('관리자 권한이 필요합니다.', 'error')
                return redirect(url_for('main.index'))
        except Exception as e:
            print(f"관리자 권한 확인 오류: {e}")
            # API 요청인 경우 JSON 응답
            if request.path.startswith('/admin/api/') or request.is_json:
                return jsonify({'error': f'권한 확인 중 오류가 발생했습니다: {str(e)}', 'success': False}), 500
            flash('권한 확인 중 오류가 발생했습니다.', 'error')
            return redirect(url_for('main.index'))
        finally:
            cur.close()
            conn.close()
        
        return f(*args, **kwargs)
    return decorated_function
