from datetime import timedelta
from flask import request
from flask import Flask
from flask_cors import CORS
from flask import send_from_directory
import os


from datetime import datetime, date

def datetimeformat(value, format='%d-%m-%Y'):
    if value is None:
        return ''
    
    # If value is datetime or date
    if isinstance(value, (datetime, date)):
        return value.strftime(format)
    
    # If value is a string, try to parse ISO format
    if isinstance(value, str):
        try:
            dt = datetime.fromisoformat(value)
            return dt.strftime(format)
        except ValueError:
            return value  # fallback if string is not parseable
    
    return value


def create_app():
    """Application factory for RateRight construction marketplace"""
    app = Flask(__name__)

    # Load configuration
    from .config import Config
    app.config.from_object(Config)

     # Register Jinja filter
    app.jinja_env.filters['datetimeformat'] = datetimeformat
    

    # Validate Stripe configuration at startup (with error handling)
    with app.app_context():
        try:
            from .services.stripe_service import validate_stripe_config
            validate_stripe_config()
        except Exception as e:
            print(f"[WARNING] Stripe validation failed: {e}")
            print("   Continuing without payment features...")

    # Initialize extensions
    from .extensions import db, jwt, migrate, login_manager, limiter, csrf
    db.init_app(app)
    migrate.init_app(app, db)
    jwt.init_app(app)
    login_manager.init_app(app)
    login_manager.login_view = 'login'
    login_manager.login_message = 'Please log in to access this page.'
    login_manager.login_message_category = 'info'
    CORS(app)
    limiter.init_app(app)
    csrf.init_app(app)

    # Configure session for Edge compatibility
    app.config.update(
        SESSION_COOKIE_SECURE=True,  # Edge requires secure cookies in production
        SESSION_COOKIE_HTTPONLY=True,  # Edge enforces HTTP-only cookies
        SESSION_COOKIE_SAMESITE='Lax',  # Edge-compatible SameSite policy
        PERMANENT_SESSION_LIFETIME=timedelta(hours=24)  # Reasonable session timeout
    )


    @app.route('/favicon.ico')
    def favicon():
        return send_from_directory(
            os.path.join(app.root_path, 'static'),
            'favicon.ico',
            mimetype='image/vnd.microsoft.icon'
        )
    
    # Add Edge compatibility headers after CORS initialization
    @app.after_request
    def add_edge_compatibility_headers(response):
        """Add headers specifically for Edge browser compatibility"""
        
        # Content Security Policy - Edge is stricter
        response.headers['Content-Security-Policy'] = (
            "default-src 'self' 'unsafe-inline' 'unsafe-eval' "
            "https://cdnjs.cloudflare.com https://cdn.jsdelivr.net "
            "https://fonts.googleapis.com https://fonts.gstatic.com https://fonts.cdnfonts.com "
            "https://js.stripe.com https://unpkg.com "
            "blob: data:; "
            "img-src 'self' data: https: https://js.stripe.com; "
            "connect-src 'self' https: wss: https://js.stripe.com"
        )
        
        # X-Content-Type-Options for Edge security
        response.headers['X-Content-Type-Options'] = 'nosniff'
        
        # X-Frame-Options for clickjacking protection
        response.headers['X-Frame-Options'] = 'SAMEORIGIN'
        
        # Referrer Policy for Edge privacy compliance
        response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
        
        # Cache Control for Edge caching issues
        if request.path.startswith('/static/'):
            response.headers['Cache-Control'] = 'public, max-age=3600'
        else:
            response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
            response.headers['Pragma'] = 'no-cache'
            response.headers['Expires'] = '0'
        
        return response


    # Add Edge-specific request preprocessing
    @app.before_request
    def handle_edge_requests():
        """Handle Edge-specific request preprocessing"""
        from flask import request
        
        # Log Edge requests for debugging
        user_agent = request.headers.get('User-Agent', '')
        if 'Edg/' in user_agent:
            print(f"[EDGE] Request to {request.path} from Edge browser")
            
            # Handle Edge DNT header sensitivity
            if request.headers.get('DNT') == '1':
                print(f"[EDGE] DNT header detected - ensuring privacy compliance")
            
            # Handle Edge's stricter cookie policies
            if 'SameSite' in request.headers.get('Cookie', ''):
                print(f"[EDGE] SameSite cookie detected")
        
        # Handle Edge preflight requests more explicitly
        if request.method == 'OPTIONS':
            print(f"[EDGE] Handling OPTIONS preflight request for {request.path}")


    # Configure Flask-Login
    @login_manager.user_loader
    def load_user(user_id):
        """Load user by ID for Flask-Login, excluding soft-deleted users"""
        from .models import User
        print(f"[DEBUG] Flask-Login user_loader called with user_id: {user_id}")
        try:
            user = User.query.get(int(user_id))
            if user:
                # Prevent deleted users from logging in
                if user.is_deleted:
                    print(f"[INFO] User {user_id} is soft-deleted, denying access")
                    return None
                print(f"[SUCCESS] User loaded: {user.email}")
                return user
            else:
                print(f"[ERROR] No user found for id: {user_id}")
                return None
        except Exception as e:
            print(f"[ERROR] Database connection failed in user_loader: {e}")
            print(f"[INFO] Clearing invalid session for user_id: {user_id}")
            # Return None to clear the invalid session
            return None

    # Configure JWT handlers
    configure_jwt_handlers(jwt)

    # Register context processors for template variables
    from .context_processors import inject_notification_counts, inject_user_context, inject_app_globals, format_job_duration
    app.context_processor(inject_notification_counts)
    app.context_processor(inject_user_context)
    app.context_processor(inject_app_globals)
    
    # Register custom Jinja filters
    app.jinja_env.filters['format_duration'] = format_job_duration

    # Register all blueprints
    register_blueprints(app)

    # Register main page routes
    from .main_routes import register_main_routes
    register_main_routes(app)

    # Add error handlers for debugging
    @app.errorhandler(404)
    def not_found(error):
        return "<h1>404 - Page Not Found</h1><p>RateRight is running but this page doesn't exist.</p>", 404

    @app.errorhandler(500)
    def internal_error(error):
        return f"<h1>500 - Internal Server Error</h1><p>RateRight encountered an error: {str(error)}</p>", 500

    return app

def configure_jwt_handlers(jwt):
    """Configure JWT error handlers"""
    from flask import jsonify

    @jwt.expired_token_loader
    def expired_token_callback(jwt_header, jwt_payload):
        return jsonify({"error": "Token has expired"}), 401

    @jwt.invalid_token_loader
    def invalid_token_callback(error):
        return jsonify({"error": "Invalid token"}), 401

    @jwt.unauthorized_loader
    def missing_token_callback(error):
        return jsonify({"error": "Authorization token is required"}), 401

def register_blueprints(app):
    """Register all Flask blueprints"""
    from .blueprints.auth import auth_bp
    from .blueprints.marketplace import marketplace_bp
    from .blueprints.legal import legal_bp
    from .blueprints.safety import safety_bp
    from .blueprints.gamification import gamification_bp
    from .blueprints.analytics import analytics_bp
    from .closeout_routes import closeout_bp
    from .routes.files import files_bp
    
    # Register admin blueprint (super admin access only)
    try:
        from .blueprints.admin import admin_bp
        app.register_blueprint(admin_bp, url_prefix='/api/admin')
        print("[SUCCESS] Registered admin blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import admin blueprint: {e}")
    
    # Register missing blueprints
    try:
        from .blueprints.scheduling import scheduling_bp
        app.register_blueprint(scheduling_bp, url_prefix='/api/scheduling')
        print("[SUCCESS] Registered scheduling blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import scheduling blueprint: {e}")
    
    try:
        from .blueprints.messages import messages_bp
        app.register_blueprint(messages_bp, url_prefix='/api/messages')
        print("[SUCCESS] Registered messages blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import messages blueprint: {e}")
    
    try:
        from .blueprints.notifications import notifications_bp
        app.register_blueprint(notifications_bp, url_prefix='/api/notifications')
        print("[SUCCESS] Registered notifications blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import notifications blueprint: {e}")

    try:
        from .blueprints.contract_dispute import contract_dispute_bp
        app.register_blueprint(contract_dispute_bp, url_prefix='/api/contract-dispute')
        print("[SUCCESS] Registered contract dispute blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import contract dispute blueprint: {e}")

    try:
        from app.blueprints.contracts import contracts_bp
        app.register_blueprint(contracts_bp)
        print("[SUCCESS] Registered contracts blueprint")
    except ImportError as e:
        print(f"[WARNING] Could not import contracts blueprint: {e}")

    app.register_blueprint(auth_bp, url_prefix='/api/auth')
    app.register_blueprint(marketplace_bp, url_prefix='/api/marketplace')
    app.register_blueprint(legal_bp, url_prefix='/api/legal')  # Register legal API routes (payments, contracts, etc.)
    app.register_blueprint(safety_bp, url_prefix='/api/safety')
    app.register_blueprint(gamification_bp, url_prefix='/api/gamification')
    app.register_blueprint(analytics_bp, url_prefix='/analytics')
    app.register_blueprint(closeout_bp, url_prefix='/api/closeout')
    app.register_blueprint(files_bp, url_prefix='/api/files')
    
    # Register legal blueprint for public document routes (no prefix)
    from .blueprints.legal.public_routes import public_legal_bp
    app.register_blueprint(public_legal_bp, url_prefix='')

    # API routes only
    @app.route('/api')
    def api_info():
        return {
            "service": "RateRight - Australian Construction Marketplace API",
            "status": "fully_operational",
            "version": "1.0.0",
            "compliance": "Australian WHS Act 2011, Fair Work Act, Tax Law",
            "api_endpoints": {
                "authentication": "/api/auth/*",
                "marketplace": "/api/marketplace/*",
                "legal_compliance": "/api/legal/*",
                "safety_system": "/api/safety/*",
                "gamification": "/api/gamification/*",
                "system_health": "/api/health"
            }
        }

    @app.route('/api/health')
    def health_check():
        from datetime import datetime
        return {
            "status": "healthy",
            "service": "RateRight Australian Construction Marketplace",
            "database": "connected",
            "timestamp": datetime.utcnow().isoformat(),
            "features": app.config.get('FEATURES', {}),
            "models_count": 15,
            "models": [
                "User", "Category", "Job", "Application", "Contract", 
                "Payment", "Invoice", "WHSAssessment", "JobProgress", 
                "Review", "Dispute", "AuditLog", "Leaderboard", 
                "Achievement", "PointActivity"
            ],
            "compliance_systems": {
                "whs_act_2011": True,
                "fair_work_act": True,
                "australian_tax_law": True,
                "abn_validation": True,
                "gst_invoicing": True
            },
            "gamification_active": app.config['FEATURES'].get('gamification_leaderboards', False)
        }
    