from .extensions import db
from flask_login import UserMixin
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash

# User model
# models.py

from app.extensions import db



class Plan(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, nullable=False)
    description = db.Column(db.Text)
    cost = db.Column(db.Float, nullable=False)
    usage_limit = db.Column(db.Integer, nullable=False)
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=db.func.current_timestamp())
    updated_at = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp())
    status = db.Column(db.String(50), nullable=False, default='active')  # Add status column
    company_plans = db.relationship('CompanyPlan', backref='plan', lazy=True)

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

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)  # Auto-incrementing primary key
    google_id = db.Column(db.String(120), unique=True, nullable=True)  # Google user ID
    first_name = db.Column(db.String(64))
    last_name = db.Column(db.String(64))
    email = db.Column(db.String(120), unique=True, index=True)
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=True)
    company_name = db.Column(db.String(120), nullable=True)  # Keep the old field
    _is_active = db.Column('is_active', db.Boolean, default=True)
    profile_picture = db.Column(db.String(200))
    password_hash = db.Column(db.String(128))
    created_at = db.Column(db.DateTime, default=db.func.current_timestamp())
    updated_at = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp())
    roles = db.relationship('Role', secondary='user_roles', backref=db.backref('users', lazy='dynamic'))
    profile = db.relationship('Profile', backref='user', uselist=False)
    notifications = db.relationship('Notification', backref='user', uselist=False)
    billing_info = db.relationship('BillingInfo', backref='user', uselist=False)
    subscription_plan = db.relationship('SubscriptionPlan', backref='user', uselist=False)



    def has_role(self, role_name):
        return any(role.name == role_name for role in self.roles)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        if self.password_hash is None:
            return False
        return check_password_hash(self.password_hash, password)

    @property
    def is_active(self):
        return self._is_active

    @is_active.setter
    def is_active(self, value):
        self._is_active = value

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


class Company(db.Model):
    __tablename__ = 'company'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    street_address = db.Column(db.String(256), nullable=True)
    city = db.Column(db.String(128), nullable=True)
    state = db.Column(db.String(128), nullable=True)
    zip_code = db.Column(db.String(20), nullable=True)
    country = db.Column(db.String(128), nullable=True)
    created_at = db.Column(db.DateTime, default=db.func.current_timestamp())
    users = db.relationship('User', backref='company', lazy=True)
    invoices = db.relationship('Invoice', back_populates='company', lazy=True)
    company_plans = db.relationship('CompanyPlan', backref='company', lazy=True)

class CompanyPlan(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'))
    plan_id = db.Column(db.Integer, db.ForeignKey('plan.id'))
    start_date = db.Column(db.DateTime, nullable=False)
    end_date = db.Column(db.DateTime, nullable=True)

class Role(db.Model):
    __tablename__ = 'role'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)


class UserRoles(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'))
    role_id = db.Column(db.Integer, db.ForeignKey('role.id', ondelete='CASCADE'))



from app import db



class UserSettings(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    theme_layout = db.Column(db.String(20), nullable=False, default='light-layout')
    direction_layout = db.Column(db.String(20), nullable=False, default='ltr-layout')
    color_theme_layout = db.Column(db.String(20), nullable=False, default='Blue_Theme')
    page_layout = db.Column(db.String(20), nullable=False, default='vertical-layout')
    layout = db.Column(db.String(20), nullable=False, default='full-layout')
    sidebar_type = db.Column(db.String(20), nullable=False, default='full-sidebar')
    card_layout = db.Column(db.String(20), nullable=False, default='card-with-border')

    user = db.relationship('User', backref=db.backref('settings', lazy=True))


class Profile(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    street_address = db.Column(db.String(120))
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    phone_number = db.Column(db.String(20))
    location = db.Column(db.String(120))
    currency = db.Column(db.String(20))
    profile_picture = db.Column(db.String(120))


class Notification(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    notification_email = db.Column(db.String(120))
    newsletter_notifications = db.Column(db.Boolean, default=False)
    invoice_notifications = db.Column(db.Boolean, default=False)
    delivery_notifications = db.Column(db.Boolean, default=False)
    email_notifications = db.Column(db.Boolean, default=False)
    message = db.Column(db.String(256), nullable=False, default=False)
    status = db.Column(db.String(50), nullable=False, default='unread')

    def __repr__(self):
        return f'<Notification {self.message}>'

class Invitation(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'))
    email = db.Column(db.String(120), unique=True, nullable=False)
    first_name = db.Column(db.String(64))
    last_name = db.Column(db.String(64))
    role = db.Column(db.String(50), nullable=False)
    token = db.Column(db.String(128), nullable=False)
    status = db.Column(db.String(50), default='pending')
    created_at = db.Column(db.DateTime, default=db.func.current_timestamp())


class BillingInfo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    business_name = db.Column(db.String(120))
    business_address = db.Column(db.String(120))
    first_name = db.Column(db.String(64))
    last_name = db.Column(db.String(64))
    business_sector = db.Column(db.String(120))
    country = db.Column(db.String(64))

class SubscriptionPlan(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    plan_name = db.Column(db.String(120))
    sites_per_month = db.Column(db.Integer)

class GISMapServer(db.Model):
    __tablename__ = 'gismapserver'
    id = db.Column(db.Integer, primary_key=True)
    url = db.Column(db.String(512), unique=True, nullable=False)
    description = db.Column(db.String(512), nullable=True)
    folders = db.relationship('Folder', backref='map_server', lazy=True)
    services = db.relationship('Service', backref='map_server', lazy=True)

class Folder(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    map_server_id = db.Column(db.Integer, db.ForeignKey('gismapserver.id'), nullable=False)
    services = db.relationship('Service', backref='folder', lazy=True)

class Service(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    type = db.Column(db.String(64), nullable=False)
    map_server_id = db.Column(db.Integer, db.ForeignKey('gismapserver.id'), nullable=True)
    folder_id = db.Column(db.Integer, db.ForeignKey('folder.id'), nullable=True)
    layers = db.relationship('Layer', backref='service', lazy=True)

class Layer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    latitude = db.Column(db.Float, nullable=True)
    longitude = db.Column(db.Float, nullable=True)
    service_id = db.Column(db.Integer, db.ForeignKey('service.id'), nullable=False)


class Invoice(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'))
    order_date = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    shipped_electronically_to = db.Column(db.String(120), nullable=False)
    plan_id = db.Column(db.Integer, db.ForeignKey('plan.id'), nullable=False)
    plan_description = db.Column(db.String(256), nullable=False)
    price = db.Column(db.Float, nullable=False)
    qty = db.Column(db.Integer, default=1, nullable=False)
    extended_price = db.Column(db.Float, nullable=False)
    subtotal = db.Column(db.Float, nullable=False)
    sales_tax = db.Column(db.Float, nullable=False)
    total = db.Column(db.Float, nullable=False)
    balance_due = db.Column(db.Float, nullable=False)
    is_paid = db.Column(db.Boolean, default=False, nullable=False)

    company = db.relationship('Company', back_populates='invoices')
    user = db.relationship('User', backref='invoices', lazy=True)
    plan = db.relationship('Plan', backref='invoices', lazy=True)

class BlockDWGData(db.Model):
    __tablename__ = 'block_dwg_data'
    id = db.Column(db.Integer, primary_key=True)
    manufacturer = db.Column(db.String(100), nullable=False)
    model = db.Column(db.String(100), nullable=False, index=True)
    block_dwg_name = db.Column(db.String(100), nullable=False)
    equipment_type = db.Column(db.String(100), nullable=False)  # New equipment type column
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)  # Foreign key to link with company

    # Relationship to the Company model
    company = db.relationship('Company', backref=db.backref('block_dwg_data', lazy=True))

    def __repr__(self):
        return f'<BlockDWGData {self.model} - {self.equipment_type} - {self.block_dwg_name}>'