import os
from datetime import datetime
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
from slugify import slugify
from werkzeug.middleware.proxy_fix import ProxyFix

from config import config
from models import db, User, BlogPost, ForumCategory, ForumTopic, ForumReply, ContactMessage


def create_app(config_name=None):
    if config_name is None:
        config_name = os.environ.get('FLASK_CONFIG', 'default')

    app = Flask(__name__)
    app.config.from_object(config[config_name])

    # Trust proxy headers from Nginx Proxy Manager → local nginx (2 proxies)
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=2, x_proto=1, x_host=1, x_prefix=1)

    db.init_app(app)

    with app.app_context():
        db.create_all()
        seed_data()

    # Context processor for templates
    @app.context_processor
    def inject_now():
        return {'now': datetime.utcnow()}

    # ==================== Company Pages ====================

    @app.route('/')
    def index():
        latest_posts = BlogPost.query.filter_by(published=True)\
            .order_by(BlogPost.created_at.desc())\
            .limit(3).all()
        return render_template('index.html', latest_posts=latest_posts)

    @app.route('/about')
    def about():
        return render_template('about.html')

    @app.route('/services')
    def services():
        return render_template('services.html')

    @app.route('/contact')
    def contact():
        return render_template('contact.html')

    @app.route('/contact/submit', methods=['POST'])
    def contact_submit():
        name = request.form.get('name')
        email = request.form.get('email')
        subject = request.form.get('subject')
        message = request.form.get('message')

        if not all([name, email, subject, message]):
            return '<div class="p-4 bg-red-100 text-red-700 rounded-lg">Please fill in all fields.</div>'

        contact_message = ContactMessage(
            name=name,
            email=email,
            subject=subject,
            message=message
        )
        db.session.add(contact_message)
        db.session.commit()

        return '''<div class="p-4 bg-green-100 text-green-700 rounded-lg">
            <strong>Thank you!</strong> Your message has been sent. We'll get back to you soon.
        </div>'''

    # ==================== Blog ====================

    @app.route('/blog')
    def blog_index():
        page = request.args.get('page', 1, type=int)
        posts = BlogPost.query.filter_by(published=True)\
            .order_by(BlogPost.created_at.desc())\
            .paginate(page=page, per_page=10, error_out=False)
        return render_template('blog/index.html', posts=posts.items)

    @app.route('/blog/search')
    def blog_search():
        query = request.args.get('search', '')
        if query:
            posts = BlogPost.query.filter_by(published=True)\
                .filter(BlogPost.title.ilike(f'%{query}%') | BlogPost.content.ilike(f'%{query}%'))\
                .order_by(BlogPost.created_at.desc())\
                .limit(10).all()
        else:
            posts = BlogPost.query.filter_by(published=True)\
                .order_by(BlogPost.created_at.desc())\
                .limit(10).all()
        return render_template('blog/partials/post_list.html', posts=posts)

    @app.route('/blog/load-more/<int:page>')
    def blog_load_more(page):
        posts = BlogPost.query.filter_by(published=True)\
            .order_by(BlogPost.created_at.desc())\
            .paginate(page=page, per_page=10, error_out=False)
        return render_template('blog/partials/post_list.html', posts=posts.items)

    @app.route('/blog/<slug>')
    def blog_post(slug):
        post = BlogPost.query.filter_by(slug=slug, published=True).first_or_404()
        return render_template('blog/post.html', post=post)

    # ==================== Forum ====================

    @app.route('/forum')
    def forum_index():
        categories = ForumCategory.query.order_by(ForumCategory.order).all()
        recent_topics = ForumTopic.query\
            .order_by(ForumTopic.created_at.desc())\
            .limit(5).all()
        return render_template('forum/index.html', categories=categories, recent_topics=recent_topics)

    @app.route('/forum/search')
    def forum_search():
        query = request.args.get('q', '')
        if query:
            topics = ForumTopic.query\
                .filter(ForumTopic.title.ilike(f'%{query}%') | ForumTopic.content.ilike(f'%{query}%'))\
                .order_by(ForumTopic.created_at.desc())\
                .limit(10).all()

            if topics:
                html = '<div class="card mb-4"><h3 class="text-lg font-semibold mb-4">Search Results</h3><div class="space-y-2">'
                for topic in topics:
                    html += f'''<a href="{url_for('forum_topic', category_slug=topic.category.slug, topic_id=topic.id)}"
                               class="block p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
                        <div class="font-medium text-gray-900">{topic.title}</div>
                        <div class="text-sm text-gray-500">in {topic.category.name}</div>
                    </a>'''
                html += '</div></div>'
                return html
            else:
                return '<div class="card mb-4 text-center text-gray-500 py-4">No topics found matching your search.</div>'
        return ''

    @app.route('/forum/<slug>')
    def forum_category(slug):
        category = ForumCategory.query.filter_by(slug=slug).first_or_404()
        page = request.args.get('page', 1, type=int)
        topics = ForumTopic.query.filter_by(category_id=category.id)\
            .order_by(ForumTopic.is_pinned.desc(), ForumTopic.created_at.desc())\
            .paginate(page=page, per_page=20, error_out=False)
        return render_template('forum/category.html', category=category, topics=topics)

    @app.route('/forum/<category_slug>/new', methods=['POST'])
    def forum_create_topic(category_slug):
        category = ForumCategory.query.filter_by(slug=category_slug).first_or_404()

        title = request.form.get('title')
        content = request.form.get('content')

        if not title or not content:
            return '<div class="p-4 bg-red-100 text-red-700 rounded-lg mb-4">Please fill in all fields.</div>'

        # Get or create a default user for demo purposes
        user = User.query.first()
        if not user:
            user = User(username='Guest', email='guest@example.com')
            user.set_password('guest')
            db.session.add(user)
            db.session.commit()

        topic = ForumTopic(
            title=title,
            content=content,
            category_id=category.id,
            author_id=user.id
        )
        db.session.add(topic)
        db.session.commit()

        # Return updated topic list
        topics = ForumTopic.query.filter_by(category_id=category.id)\
            .order_by(ForumTopic.is_pinned.desc(), ForumTopic.created_at.desc())\
            .paginate(page=1, per_page=20, error_out=False)
        return render_template('forum/partials/topic_list.html', category=category, topics=topics)

    @app.route('/forum/<category_slug>/<int:topic_id>')
    def forum_topic(category_slug, topic_id):
        topic = ForumTopic.query.get_or_404(topic_id)
        replies = topic.replies.order_by(ForumReply.created_at.asc()).all()
        return render_template('forum/topic.html', topic=topic, replies=replies)

    @app.route('/forum/<category_slug>/<int:topic_id>/reply', methods=['POST'])
    def forum_add_reply(category_slug, topic_id):
        topic = ForumTopic.query.get_or_404(topic_id)

        if topic.is_locked:
            return '<div class="p-4 bg-red-100 text-red-700 rounded-lg">This topic is locked.</div>'

        content = request.form.get('content')
        if not content:
            return '<div class="p-4 bg-red-100 text-red-700 rounded-lg">Please enter a reply.</div>'

        # Get or create a default user for demo purposes
        user = User.query.first()
        if not user:
            user = User(username='Guest', email='guest@example.com')
            user.set_password('guest')
            db.session.add(user)
            db.session.commit()

        reply = ForumReply(
            content=content,
            topic_id=topic.id,
            author_id=user.id
        )
        db.session.add(reply)
        db.session.commit()

        # Return the new reply as HTML
        return f'''<div class="card mb-4">
            <div class="flex items-start">
                <div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center text-gray-600 font-semibold flex-shrink-0">
                    {reply.author.username[0].upper()}
                </div>
                <div class="ml-4 flex-grow">
                    <div class="flex items-center justify-between mb-2">
                        <div class="font-medium text-gray-900">{reply.author.username}</div>
                        <div class="text-sm text-gray-500">{reply.created_at.strftime('%B %d, %Y at %H:%M')}</div>
                    </div>
                    <div class="prose prose-sm max-w-none text-gray-600">
                        {reply.content}
                    </div>
                </div>
            </div>
        </div>'''

    return app


def seed_data():
    """Seed the database with sample data if empty."""
    if User.query.first() is None:
        # Create admin user
        admin = User(username='admin', email='admin@directlx.dev', is_admin=True)
        admin.set_password('admin123')
        db.session.add(admin)

        # Create sample blog posts
        posts = [
            {
                'title': 'Getting Started with Flask and HTMX',
                'slug': 'getting-started-flask-htmx',
                'excerpt': 'Learn how to build modern, interactive web applications using Flask and HTMX.',
                'content': '''<p>Flask and HTMX make a powerful combination for building interactive web applications without the complexity of a JavaScript framework.</p>
                <h2>Why HTMX?</h2>
                <p>HTMX allows you to access modern browser features directly from HTML, making it easy to build dynamic user interfaces with minimal JavaScript.</p>
                <h2>Getting Started</h2>
                <p>First, create a new Flask project and install the required dependencies. Then, add HTMX to your templates and start building interactive features.</p>''',
                'published': True
            },
            {
                'title': 'Building Scalable APIs with Python',
                'slug': 'building-scalable-apis-python',
                'excerpt': 'Best practices for designing and building scalable REST APIs using Python.',
                'content': '''<p>Building scalable APIs requires careful planning and adherence to best practices.</p>
                <h2>Design Principles</h2>
                <p>Follow REST principles, use proper HTTP methods, and design your endpoints to be intuitive and consistent.</p>
                <h2>Performance Considerations</h2>
                <p>Implement caching, pagination, and rate limiting to ensure your API can handle high traffic.</p>''',
                'published': True
            },
            {
                'title': 'The Future of Web Development',
                'slug': 'future-web-development',
                'excerpt': 'Exploring emerging trends and technologies shaping the future of web development.',
                'content': '''<p>The web development landscape is constantly evolving. Let's explore what's next.</p>
                <h2>Emerging Trends</h2>
                <p>From WebAssembly to edge computing, new technologies are changing how we build web applications.</p>
                <h2>What This Means for Developers</h2>
                <p>Staying current with these trends will help you build better applications and advance your career.</p>''',
                'published': True
            }
        ]

        for post_data in posts:
            post = BlogPost(author_id=1, **post_data)
            db.session.add(post)

        # Create forum categories
        categories = [
            {'name': 'General Discussion', 'slug': 'general', 'description': 'General topics and discussions about software development.', 'order': 1},
            {'name': 'Help & Support', 'slug': 'help', 'description': 'Get help with technical problems and questions.', 'order': 2},
            {'name': 'Showcase', 'slug': 'showcase', 'description': 'Share your projects and get feedback from the community.', 'order': 3},
            {'name': 'Off Topic', 'slug': 'off-topic', 'description': 'Everything else that doesn\'t fit elsewhere.', 'order': 4}
        ]

        for cat_data in categories:
            category = ForumCategory(**cat_data)
            db.session.add(category)

        db.session.commit()

        # Create sample forum topics
        general = ForumCategory.query.filter_by(slug='general').first()
        if general:
            topic = ForumTopic(
                title='Welcome to the DirectLX Community!',
                content='Welcome everyone! This is a place to discuss software development, share knowledge, and connect with other developers. Feel free to introduce yourself!',
                category_id=general.id,
                author_id=1,
                is_pinned=True
            )
            db.session.add(topic)
            db.session.commit()


# Create the application instance
app = create_app()

if __name__ == '__main__':
    app.run(debug=True, port=5000)
