from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime, timedelta
import secrets

db = SQLAlchemy()

class User(db.Model):
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False, index=True)
    password_hash = db.Column(db.String(255), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    full_name = db.Column(db.String(100))
    job_title = db.Column(db.String(100), default='Property Manager')
    phone_number = db.Column(db.String(20))
    profile_picture = db.Column(db.Text)  # Base64 encoded image or URL
    
    # Company information
    company_name = db.Column(db.String(200))
    company_logo = db.Column(db.Text)  # Base64 encoded image or URL
    license_number = db.Column(db.String(50))
    company_address = db.Column(db.Text)
    company_phone = db.Column(db.String(20))
    company_email = db.Column(db.String(120))
    
    # Owner information (default values for reports)
    owner_name = db.Column(db.String(100))
    owner_email = db.Column(db.String(120))
    owner_phone = db.Column(db.String(20))
    
    # Account management
    is_active = db.Column(db.Boolean, default=True)
    email_verified = db.Column(db.Boolean, default=False)
    verification_token = db.Column(db.String(100))
    reset_token = db.Column(db.String(100))
    reset_token_expires = db.Column(db.DateTime)
    
    # Timestamps
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    last_login = db.Column(db.DateTime)
    
    def set_password(self, password):
        """Set password hash"""
        self.password_hash = generate_password_hash(password)
    
    def check_password(self, password):
        """Check if provided password matches hash"""
        return check_password_hash(self.password_hash, password)
    
    def generate_verification_token(self):
        """Generate email verification token"""
        self.verification_token = secrets.token_urlsafe(32)
        return self.verification_token
    
    def generate_reset_token(self):
        """Generate password reset token"""
        self.reset_token = secrets.token_urlsafe(32)
        self.reset_token_expires = datetime.utcnow() + timedelta(hours=1)
        return self.reset_token
    
    def to_dict(self):
        """Convert user object to dictionary"""
        return {
            'id': self.id,
            'email': self.email,
            'name': self.name,
            'full_name': self.full_name,
            'job_title': self.job_title,
            'phone_number': self.phone_number,
            'profile_picture': self.profile_picture,
            'company_name': self.company_name,
            'company_logo': self.company_logo,
            'license_number': self.license_number,
            'company_address': self.company_address,
            'company_phone': self.company_phone,
            'company_email': self.company_email,
            'owner_name': self.owner_name,
            'owner_email': self.owner_email,
            'owner_phone': self.owner_phone,
            'is_active': self.is_active,
            'email_verified': self.email_verified,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'last_login': self.last_login.isoformat() if self.last_login else None
        }
    
    def __repr__(self):
        return f'<User {self.email}>'


class Inspection(db.Model):
    __tablename__ = 'inspections'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    property_address = db.Column(db.String(500), nullable=False)
    inspection_date = db.Column(db.DateTime, default=datetime.utcnow)
    status = db.Column(db.String(50), default='in_progress')  # in_progress, completed, draft
    
    # Inspection data (JSON stored as text)
    exterior_data = db.Column(db.Text)  # JSON string
    interior_data = db.Column(db.Text)  # JSON string
    systems_data = db.Column(db.Text)  # JSON string
    
    # Additional notes and voice memos
    additional_notes = db.Column(db.Text)
    voice_memos = db.Column(db.Text)  # JSON string of voice memo data
    
    # Photos (JSON array of base64 encoded images or URLs)
    photos = db.Column(db.Text)  # JSON string
    
    # Report generation
    report_generated = db.Column(db.Boolean, default=False)
    report_sent = db.Column(db.Boolean, default=False)
    report_sent_to = db.Column(db.String(120))
    
    # Timestamps
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    completed_at = db.Column(db.DateTime)
    
    # Relationship
    user = db.relationship('User', backref=db.backref('inspections', lazy=True))
    
    def to_dict(self):
        """Convert inspection object to dictionary"""
        return {
            'id': self.id,
            'user_id': self.user_id,
            'property_address': self.property_address,
            'inspection_date': self.inspection_date.isoformat() if self.inspection_date else None,
            'status': self.status,
            'exterior_data': self.exterior_data,
            'interior_data': self.interior_data,
            'systems_data': self.systems_data,
            'additional_notes': self.additional_notes,
            'voice_memos': self.voice_memos,
            'photos': self.photos,
            'report_generated': self.report_generated,
            'report_sent': self.report_sent,
            'report_sent_to': self.report_sent_to,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
            'completed_at': self.completed_at.isoformat() if self.completed_at else None
        }
    
    def __repr__(self):
        return f'<Inspection {self.id} - {self.property_address}>'

