"""
Main blueprint - contains public and user-facing routes.
"""
import os
import secrets
from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_required, current_user
from PIL import Image
from app.models import db, Product, CartItem, Order, OrderItem
from app.forms import ProfileForm
from app.routes.utils import save_image


main_bp = Blueprint('main', __name__)


@main_bp.route('/')
def home():
    """Home page."""
    # Get featured products for homepage
    products = Product.query.limit(3).all()
    return render_template('index.html', products=products)


@main_bp.route('/about')
def about():
    """About page."""
    return render_template('about.html')


@main_bp.route('/products')
def products():
    """Products page."""
    all_products = Product.query.all()
    return render_template('products.html', products=all_products)


@main_bp.route('/add-to-cart', methods=['POST'])
@login_required
def add_to_cart():
    """Add product to user's cart."""
    product_id = request.form.get('product_id')
    try:
        quantity = int(request.form.get('quantity', 1))
    except (ValueError, TypeError):
        quantity = 1

    if not product_id:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({'success': False, 'message': 'Product not found.'})
        flash('Product not found.', 'error')
        return redirect(url_for('main.products'))

    product = Product.query.get(product_id)
    if not product:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({'success': False, 'message': 'Product not found.'})
        flash('Product not found.', 'error')
        return redirect(url_for('main.products'))

    # Check if item already in cart
    existing_item = CartItem.query.filter_by(
        user_id=current_user.id,
        product_id=product_id
    ).first()

    if existing_item:
        existing_item.quantity += quantity
        message = f'Updated quantity of {product.name} in your cart.'
    else:
        new_item = CartItem(
            user_id=current_user.id,
            product_id=product_id,
            quantity=quantity
        )
        db.session.add(new_item)
        message = f'{product.name} added to your cart!'

    db.session.commit()
    
    # Get updated cart count
    cart_count = CartItem.query.filter_by(user_id=current_user.id).count()
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return jsonify({
            'success': True,
            'message': message,
            'cart_count': cart_count
        })
    
    flash(message, 'success')
    return redirect(url_for('main.products'))


@main_bp.route('/cart')
@login_required
def view_cart():
    """View user's shopping cart."""
    cart_items = CartItem.query.filter_by(user_id=current_user.id).all()
    total_price = sum(item.quantity * item.product.price for item in cart_items)
    return render_template('cart.html', cart_items=cart_items, total_price=total_price)


@main_bp.route('/remove-from-cart/<int:item_id>', methods=['POST'])
@login_required
def remove_from_cart(item_id):
    """Remove item from cart."""
    item = CartItem.query.filter_by(id=item_id, user_id=current_user.id).first()

    if item:
        product_name = item.product.name
        db.session.delete(item)
        db.session.commit()
        
        # Check if AJAX request
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            # Calculate new total
            remaining_items = CartItem.query.filter_by(user_id=current_user.id).all()
            total = sum(i.quantity * i.product.price for i in remaining_items)
            return jsonify({
                'success': True,
                'message': f'{product_name} removed from your cart.',
                'total': total
            })
        
        flash(f'{product_name} removed from your cart.', 'success')
    else:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({'success': False, 'message': 'Item not found in your cart.'})
        flash('Item not found in your cart.', 'error')

    return redirect(url_for('main.view_cart'))


@main_bp.route('/update-cart/<int:item_id>', methods=['POST'])
@login_required
def update_cart(item_id):
    """Update cart item quantity."""
    try:
        new_quantity = int(request.form.get('quantity', 1))
    except (ValueError, TypeError):
        new_quantity = 1

    if new_quantity < 1:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({'success': False, 'message': 'Quantity must be at least 1.'})
        flash('Quantity must be at least 1.', 'error')
        return redirect(url_for('main.view_cart'))

    item = CartItem.query.filter_by(id=item_id, user_id=current_user.id).first()

    if item:
        item.quantity = new_quantity
        db.session.commit()
        
        # Calculate subtotal and total
        subtotal = item.quantity * item.product.price
        all_items = CartItem.query.filter_by(user_id=current_user.id).all()
        total = sum(i.quantity * i.product.price for i in all_items)
        
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': True,
                'message': 'Cart updated successfully.',
                'subtotal': subtotal,
                'total': total
            })
        
        flash('Cart updated successfully.', 'success')
    else:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({'success': False, 'message': 'Item not found in your cart.'})
        flash('Item not found in your cart.', 'error')

    return redirect(url_for('main.view_cart'))


@main_bp.route('/checkout')
@login_required
def checkout():
    """Checkout page showing order summary and payment details."""
    cart_items = CartItem.query.filter_by(user_id=current_user.id).all()
    
    if not cart_items:
        flash('Your cart is empty. Add some products first!', 'error')
        return redirect(url_for('main.products'))
    
    total_price = sum(item.quantity * item.product.price for item in cart_items)
    return render_template('checkout.html', cart_items=cart_items, total_price=total_price)


@main_bp.route('/complete-order')
@login_required
def complete_order():
    """Complete the order and clear the cart."""
    cart_items = CartItem.query.filter_by(user_id=current_user.id).all()
    
    if cart_items:
        # Calculate total price
        total_price = sum(item.quantity * item.product.price for item in cart_items)
        
        # Create order
        order = Order(
            user_id=current_user.id,
            total_amount=total_price,
            status='pending'
        )
        db.session.add(order)
        db.session.flush()  # Get the order ID
        
        # Create order items from cart items
        for item in cart_items:
            order_item = OrderItem(
                order_id=order.id,
                product_id=item.product_id,
                product_name=item.product.name,
                price=item.product.price,
                quantity=item.quantity
            )
            db.session.add(order_item)
        
        # Delete all items from the cart
        for item in cart_items:
            db.session.delete(item)
        
        db.session.commit()
        flash('Order completed successfully! Thank you for your purchase.', 'success')
    else:
        flash('Your cart is empty.', 'error')
    
    return redirect(url_for('main.products'))


@main_bp.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
    """User profile page for updating account information and viewing orders."""
    form = ProfileForm(original_email=current_user.email)
    
    if form.validate_on_submit():
        # Update user information
        current_user.full_name = form.full_name.data
        current_user.email = form.email.data
        
        # Handle profile picture upload
        if form.profile_picture.data:
            image_path = save_image(form.profile_picture.data)
            if image_path:
                current_user.profile_picture = image_path
        
        try:
            db.session.commit()
            flash('Profile updated successfully!', 'success')
            return redirect(url_for('main.profile'))
        except Exception as e:
            db.session.rollback()
            flash('An error occurred while updating your profile. Please try again.', 'error')
    elif request.method == 'GET':
        # Pre-populate form with current user data
        form.full_name.data = current_user.full_name
        form.email.data = current_user.email
    
    # Get user's orders
    orders = Order.query.filter_by(user_id=current_user.id).order_by(Order.created_at.desc()).all()
    
    return render_template('profile.html', form=form, orders=orders)