from datetime import datetime
import os
from sqlalchemy import (
    ARRAY, DECIMAL, BigInteger, Column, Date, Integer, String, DateTime, Boolean, JSON, Enum, ForeignKey, Index,Text, UniqueConstraint,
)
from sqlalchemy.sql import func
from src.core.database import Base
from src.constants import CompanyPlanEnum
from src.core.utils import generate_uuid
from sqlalchemy.orm import relationship
import enum

# FERNET_KEY = os.environ["TENANT_DB_FERNET_KEY"].encode()
class Company(Base):
    __tablename__ = "companies"

    id = Column(String, primary_key=True, index=True, default=generate_uuid)
    company_name = Column(String(100), nullable=False)
    legal_name = Column(String(150), nullable=True)
    bio = Column(String(500), nullable=True)
    address = Column(Text, nullable=True)
    home_country = Column(String(100), nullable=True)
    company_logo_url = Column(String(255), nullable=True)
    has_branches = Column(Boolean, default=False, nullable=False)
    users_count = Column(Integer, default=1, nullable=True)

    email = Column(String(100), unique=True, index=True, nullable=False)
    phone_number = Column(String(20), nullable=True)

    db_name = Column(String(100), unique=True, index=True, nullable=True)
    db_host = Column(String(100), default="localhost", nullable=True)
    db_port = Column(String(6), default="5432", nullable=True)
    is_2FA_enabled = Column(Boolean, default=False, nullable=False)

    plan = Column(Enum(CompanyPlanEnum), default=CompanyPlanEnum.BASIC, nullable=False)
    trial_ends_at = Column(DateTime(timezone=True), nullable=True)
    next_billing_date = Column(DateTime(timezone=True), nullable=True)
    is_active = Column(Boolean, default=True, nullable=False)
    settings = Column(JSON, default=dict)

    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), nullable=True)
    deleted_at = Column(DateTime(timezone=True), nullable=True)

    subscriptions = relationship("Subscription", back_populates="company")
    

# Optional extra index    
# Index("ix_companies_db_name", Company.db_name)

class BillingCycle(str, enum.Enum):
    monthly = "monthly"
    yearly = "yearly"
    


# 1. Departments
class Department(Base):
    __tablename__ = "departments"

    department_id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String(100),unique=True, nullable=False)
    description = Column(Text)
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)


# 2. Roles
class Role(Base):
    __tablename__ = "roles"

    role_id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String(100),unique=True, nullable=False)
    description = Column(Text)
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

class RoleDepartment(Base):
    __tablename__ = "role_department"

    role_department_id = Column(BigInteger, primary_key=True, autoincrement=True)
    role_id = Column(BigInteger, ForeignKey("roles.role_id", ondelete="CASCADE"), nullable=False)
    department_id = Column(BigInteger, ForeignKey("departments.department_id", ondelete="CASCADE"), nullable=False)

    __table_args__ = (UniqueConstraint('role_id', 'department_id', name='_role_department_uc'),)

    role = relationship("Role")
    department = relationship("Department")

    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

    user_roles = relationship("UserRole", back_populates="role_department")
    permissions = relationship("RoleDepartmentPermission", back_populates="role_department")



# 4. Modules
class Module(Base):
    __tablename__ = "modules"

    module_id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String,unique=True, nullable=False)
    description = Column(Text)
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

# 5. Subscription Plans
class SubscriptionPlan(Base):
    __tablename__ = "subscription_plans"

    subscription_plan_id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String,unique=True, nullable=False)
    billing_cycle = Column(Enum(BillingCycle), nullable=False)
    price = Column(String, nullable=False)
    collaborators=Column(Integer,default=0,nullable=False)
    business_users=Column(Integer,default=0,nullable=False)
    view_only=Column(Integer,default=0,nullable=False)
    user_limit = Column(Integer, nullable=False) 
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

    inquiries = relationship("Inquiry", back_populates="subscription_plan")



# 6. PlanModules (Many-to-Many between plans and modules)
class PlanModule(Base):
    __tablename__ = "plan_modules"

    plan_id = Column(BigInteger, ForeignKey("subscription_plans.subscription_plan_id", ondelete="CASCADE"), primary_key=True)
    module_id = Column(BigInteger, ForeignKey("modules.module_id", ondelete="CASCADE"), primary_key=True)

    plan = relationship("SubscriptionPlan")
    module = relationship("Module")
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)


class RoleDepartmentPermission(Base):
    __tablename__ = "role_department_permissions"

    role_department_permission_id = Column(BigInteger, primary_key=True, autoincrement=True)
    role_department_id = Column(BigInteger, ForeignKey("role_department.role_department_id", ondelete="CASCADE"), nullable=False)
    permission_id = Column(BigInteger, ForeignKey("permissions.permission_id", ondelete="CASCADE"), nullable=False)

    __table_args__ = (UniqueConstraint('role_department_id', 'permission_id', name='_rd_permission_uc'),)

    role_department = relationship("RoleDepartment", back_populates="permissions")
    permission = relationship("Permission", back_populates="role_department_permissions")

    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)



class UserRole(Base):
    __tablename__ = "user_roles"

    user_role_id = Column(BigInteger, primary_key=True, autoincrement=True)
    user_id = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
    role_department_id = Column(BigInteger, ForeignKey("role_department.role_department_id", ondelete="CASCADE"), nullable=False)
    company_id = Column(String, ForeignKey("companies.id", ondelete="CASCADE"), nullable=False)

    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

    __table_args__ = (UniqueConstraint('user_id', 'role_department_id', 'company_id', name='_user_role_uc'),)

    user = relationship("User", back_populates="user_roles")
    role_department = relationship("RoleDepartment", back_populates="user_roles")

class Permission(Base):
    __tablename__ = "permissions"

    permission_id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String(100),unique=True, nullable=False)
    module_id = Column(BigInteger, ForeignKey("modules.module_id", ondelete="CASCADE"), nullable=False)
    description = Column(Text)

    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

    module = relationship("Module")
    role_department_permissions = relationship("RoleDepartmentPermission", back_populates="permission")


# 10. Subscriptions
class Subscription(Base):
    __tablename__ = "subscriptions"
    
    subscription_id = Column(BigInteger, primary_key=True, autoincrement=True)
    company_id = Column(String, ForeignKey("companies.id"), nullable=False)
    plan_id = Column(BigInteger, ForeignKey("subscription_plans.subscription_plan_id"), nullable=False)
    collaborators=Column(Integer,default=0,nullable=False)
    business_users=Column(Integer,default=0,nullable=False)
    view_only=Column(Integer,default=0,nullable=False)
    price = Column(String, nullable=False)
    start_date = Column(Date, nullable=False)

    end_date = Column(Date)
    status = Column(String(20))  # e.g., active, expired, trial
    create_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)

    plan = relationship("SubscriptionPlan")
    company = relationship("Company", back_populates="subscriptions")




class DemoBooking(Base):
    __tablename__ = "demo_bookings"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, nullable=False)
    company = Column(String, nullable=False)
    email = Column(String, nullable=False)
    interests = Column(String, nullable=True)  # store as comma-separated string
    message = Column(Text, nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)


# Existing DemoBooking model remains here...

class Inquiry(Base):
    __tablename__ = "inquiries"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, nullable=False)
    phone = Column(String, nullable=True)
    company = Column(String, nullable=True)
    additional_message = Column(Text, nullable=True)
    subscription_plan_id = Column(BigInteger, ForeignKey("subscription_plans.subscription_plan_id"), nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)
    subscription_plan = relationship("SubscriptionPlan", back_populates="inquiries")
from enum import Enum
class BlogStatusEnum(str,Enum):
    DRAFT = "draft"
    PUBLISHED = "published"
    ARCHIVED = "archived"
from sqlalchemy import Enum as SqlEnum

class Blog(Base):
    __tablename__ = "blogs"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, nullable=False)
    content = Column(Text, nullable=False)
    author = Column(String, nullable=False)
    status = Column(
    SqlEnum(BlogStatusEnum, name="blog_status"),
    default=BlogStatusEnum.DRAFT,
    nullable=False
)        
    image= Column(String, nullable=True)  # make sure BlogCreate has image_path attribute

    tags = Column(ARRAY(String))
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    meta_title = Column(String , nullable = False)
    meta_description = Column(String , nullable = False)
    alt_text = Column(String)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
