from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime, timezone
from sqlalchemy import Enum
from .db import db
import enum

class SubscriptionType(enum.Enum):
    """구독 타입"""
    MONTHLY = "monthly"  # 월 기준 구독자 (기존 가입자)
    CREDIT = "credit"  # 크레딧 기준 구독자 (신규 가입자, 기본값)

class User(db.Model):
    __tablename__ = 'user'
    
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.String(20), unique=True, nullable=False)
    username = db.Column(db.String(255), unique=True, nullable=False)  # OAuth username 길이 대응
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)
    is_active = db.Column(db.Boolean, default=True)
    subscription_type = db.Column(Enum(SubscriptionType), default=SubscriptionType.CREDIT, nullable=False)  # 구독 타입 (기본값: 크레딧 기준)
    created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
    
    # 구독 서비스 관련 관계 (DB FK 없음: User.user_id == 자식.user_id)
    profile = db.relationship(
        'UserProfile', back_populates='user', uselist=False,
        primaryjoin='User.user_id==UserProfile.user_id',
        foreign_keys='UserProfile.user_id',
    )
    subscriptions = db.relationship(
        'Subscription', back_populates='user',
        primaryjoin='User.user_id==Subscription.user_id',
        foreign_keys='Subscription.user_id',
    )
    payments = db.relationship(
        'Payment', back_populates='user',
        primaryjoin='User.user_id==Payment.user_id',
        foreign_keys='Payment.user_id',
    )
    payment_histories = db.relationship(
        'PaymentHistory', back_populates='user',
        primaryjoin='User.user_id==PaymentHistory.user_id',
        foreign_keys='PaymentHistory.user_id',
    )
    content_access = db.relationship(
        'UserContentAccess', back_populates='user',
        primaryjoin='User.user_id==UserContentAccess.user_id',
        foreign_keys='UserContentAccess.user_id',
    )

    # 크레딧 관련 관계
    credit_transactions = db.relationship(
        'CreditTransaction', back_populates='user',
        order_by='CreditTransaction.created_at.desc()',
        primaryjoin='User.user_id==CreditTransaction.user_id',
        foreign_keys='CreditTransaction.user_id',
    )
    credit_balance = db.relationship(
        'CreditBalance', back_populates='user', uselist=False,
        primaryjoin='User.user_id==CreditBalance.user_id',
        foreign_keys='CreditBalance.user_id',
    )
    event_credit_lots = db.relationship(
        'EventCreditLot', back_populates='user',
        order_by='EventCreditLot.expires_at.asc()',
        primaryjoin='User.user_id==EventCreditLot.user_id',
        foreign_keys='EventCreditLot.user_id',
    )

    def set_password(self, password):
        """비밀번호 설정 - werkzeug 해시 사용"""
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        """비밀번호 검증 - werkzeug 해시 사용"""
        return check_password_hash(self.password_hash, password)

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'username': self.username,
            'email': self.email,
            'is_active': self.is_active,
            'subscription_type': self.subscription_type.value if self.subscription_type else SubscriptionType.CREDIT.value,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }

    def __repr__(self):
        return f'<User {self.username}>'

