# models.py - Complete database models with Paystack integration
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from datetime import datetime, timedelta
import uuid

db = SQLAlchemy()

class Organization(db.Model):
    __tablename__ = 'organizations'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    slug = db.Column(db.String(100), unique=True, nullable=False)
    size = db.Column(db.String(50), nullable=False)  # startup, small, medium, large, enterprise
    industry = db.Column(db.String(100), nullable=False)

    # Subscription details
    subscription_plan = db.Column(db.String(50), default='free')  # free, professional, enterprise
    subscription_status = db.Column(db.String(20), default='active')
    
    # Paystack integration (replacing Stripe)
    paystack_customer_code = db.Column(db.String(100), unique=True)
    paystack_subscription_code = db.Column(db.String(100), unique=True)
    
    trial_ends_at = db.Column(db.DateTime)
    subscription_ends_at = db.Column(db.DateTime)

    # Usage limits and tracking
    monthly_assessments_limit = db.Column(db.Integer, default=5)
    monthly_assessments_used = db.Column(db.Integer, default=0)
    assessments_reset_date = db.Column(db.DateTime, default=lambda: datetime.utcnow().replace(day=1))

    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # Relationships
    users = db.relationship('User', backref='organization', lazy=True)
    assessments = db.relationship('Assessment', backref='organization', lazy=True)
    invoices = db.relationship('Invoice', backref='organization', lazy=True)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        if not self.slug:
            self.slug = self.generate_slug()
        if self.subscription_plan == 'free':
            self.trial_ends_at = datetime.utcnow() + timedelta(days=14)

    def generate_slug(self):
        base_slug = self.name.lower().replace(' ', '-').replace('&', 'and')
        return f"{base_slug}-{str(uuid.uuid4())[:8]}"

    def can_create_assessment(self):
        if self.subscription_plan == 'free':
            return self.monthly_assessments_used < self.monthly_assessments_limit
        return True

    def is_trial_expired(self):
        if self.trial_ends_at:
            return datetime.utcnow() > self.trial_ends_at
        return False

    def reset_monthly_usage_if_needed(self):
        """Reset monthly usage counter if it's a new month"""
        now = datetime.utcnow()
        if self.assessments_reset_date and now >= self.assessments_reset_date:
            self.monthly_assessments_used = 0
            # Set next reset date to first day of next month
            if now.month == 12:
                self.assessments_reset_date = datetime(now.year + 1, 1, 1)
            else:
                self.assessments_reset_date = datetime(now.year, now.month + 1, 1)

class User(UserMixin, db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(100), nullable=False)
    last_name = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(255), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)

    # Organization relationship
    organization_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=False)
    role = db.Column(db.String(50), default='member')  # admin, member, viewer

    # Profile
    avatar_url = db.Column(db.String(500))
    job_title = db.Column(db.String(100))
    phone = db.Column(db.String(20))

    # Account status
    is_active = db.Column(db.Boolean, default=True)
    is_verified = db.Column(db.Boolean, default=False)
    verification_token = db.Column(db.String(100))

    # Timestamps
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    last_login_at = db.Column(db.DateTime)

    def get_full_name(self):
        return f"{self.first_name} {self.last_name}"

    def can_manage_org(self):
        return self.role == 'admin'

class Assessment(db.Model):
    __tablename__ = 'assessments'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text)

    # Repository details
    repository_url = db.Column(db.String(500), nullable=False)
    platform = db.Column(db.String(50), nullable=False)  # github, gitlab, azure, jenkins
    branch = db.Column(db.String(100), default='main')

    # Organization and user
    organization_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=False)
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

    # Assessment status
    status = db.Column(db.String(20), default='pending')  # pending, running, completed, failed
    overall_score = db.Column(db.Float)
    maturity_level = db.Column(db.String(20))  # initial, managed, defined, quantitative, optimized

    # Category scores (out of 100)
    source_code_security_score = db.Column(db.Float)
    build_security_score = db.Column(db.Float)
    deployment_security_score = db.Column(db.Float)
    runtime_security_score = db.Column(db.Float)
    compliance_score = db.Column(db.Float)
    culture_score = db.Column(db.Float)

    # Metadata
    pipeline_files_found = db.Column(db.JSON)  # List of pipeline files
    tools_detected = db.Column(db.JSON)  # List of security tools found
    recommendations = db.Column(db.JSON)  # List of recommendations

    # Timestamps
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    completed_at = db.Column(db.DateTime)

    # Relationships
    creator = db.relationship('User', backref='created_assessments')

class Subscription(db.Model):
    __tablename__ = 'subscriptions'

    id = db.Column(db.Integer, primary_key=True)
    organization_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=False)

    # Paystack details (replacing Stripe)
    paystack_subscription_code = db.Column(db.String(100), unique=True)
    paystack_customer_code = db.Column(db.String(100))
    paystack_plan_code = db.Column(db.String(100))

    # Subscription details
    plan = db.Column(db.String(50), nullable=False)  # free, professional, enterprise
    status = db.Column(db.String(20), nullable=False)  # active, canceled, past_due
    current_period_start = db.Column(db.DateTime)
    current_period_end = db.Column(db.DateTime)

    # Billing
    amount = db.Column(db.Integer)  # Amount in kobo (Paystack uses kobo for KES)
    currency = db.Column(db.String(3), default='KES')

    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # Relationship
    organization = db.relationship('Organization', backref=db.backref('subscription', uselist=False))

class Invoice(db.Model):
    __tablename__ = 'invoices'

    id = db.Column(db.Integer, primary_key=True)
    organization_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=False)

    # Paystack details (replacing Stripe)
    paystack_invoice_id = db.Column(db.String(100), unique=True)
    paystack_transaction_reference = db.Column(db.String(100))

    # Invoice details
    amount = db.Column(db.Float, nullable=False)  # Amount in KES
    currency = db.Column(db.String(10), default='KES')
    status = db.Column(db.String(50), nullable=False)  # paid, pending, failed, cancelled

    # Dates
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    paid_at = db.Column(db.DateTime)
    due_date = db.Column(db.DateTime)

    # Additional Paystack fields
    payment_method = db.Column(db.String(50))  # card, bank_transfer, mobile_money
    gateway_response = db.Column(db.Text)  # Store Paystack response for debugging
