"""
Admin blueprint - dashboard and product management routes.
"""
from flask import Blueprint, render_template, redirect, url_for, flash, request, abort
from flask_login import login_required, current_user
from functools import wraps
from app.models import db, Product, Order
from app.forms import ProductForm
from app.routes.utils import save_image


admin_bp = Blueprint('admin', __name__, url_prefix='/admin')


def admin_required(f):
    """Decorator to require admin access for routes."""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('Please log in to access this page.', 'error')
            return redirect(url_for('auth.login'))
        if not current_user.is_admin:
            flash('You do not have permission to access this page.', 'error')
            abort(403)
        return f(*args, **kwargs)
    return decorated_function


@admin_bp.route('/')
@admin_required
def dashboard():
    """Admin dashboard showing products and orders."""
    products = Product.query.order_by(Product.created_at.desc()).all()
    orders = Order.query.order_by(Order.created_at.desc()).limit(10).all()
    
    return render_template('admin/dashboard.html', products=products, orders=orders)


@admin_bp.route('/product/add', methods=['GET', 'POST'])
@admin_required
def add_product():
    """Add a new product."""
    form = ProductForm()
    if form.validate_on_submit():
        # Handle image upload
        image_path = None
        if form.image.data:
            image_path = save_image(form.image.data)
        
        new_product = Product(
            name=form.name.data,
            price=form.price.data,
            image_url=image_path,
            badge=form.badge.data if form.badge.data else None,
            description=form.description.data,
            quantity_available=form.quantity_available.data
        )
        
        try:
            db.session.add(new_product)
            db.session.commit()
            flash(f'Product "{new_product.name}" added successfully!', 'success')
            return redirect(url_for('admin.dashboard'))
        except Exception as e:
            db.session.rollback()
            flash('An error occurred while adding the product. Please try again.', 'error')
    
    return render_template('admin/product_form.html', form=form, title='Add Product')


@admin_bp.route('/product/edit/<int:product_id>', methods=['GET', 'POST'])
@admin_required
def edit_product(product_id):
    """Edit an existing product."""
    product = Product.query.get_or_404(product_id)
    form = ProductForm(obj=product)
    
    if form.validate_on_submit():
        product.name = form.name.data
        product.price = form.price.data
        
        # Handle image upload
        if form.image.data:
            image_path = save_image(form.image.data)
            if image_path:
                product.image_url = image_path
        
        product.badge = form.badge.data if form.badge.data else None
        product.description = form.description.data
        product.quantity_available = form.quantity_available.data
        
        try:
            db.session.commit()
            flash(f'Product "{product.name}" updated successfully!', 'success')
            return redirect(url_for('admin.dashboard'))
        except Exception as e:
            db.session.rollback()
            flash('An error occurred while updating the product. Please try again.', 'error')
    
    return render_template('admin/product_form.html', form=form, title='Edit Product', product=product)


@admin_bp.route('/product/delete/<int:product_id>', methods=['POST'])
@admin_required
def delete_product(product_id):
    """Delete a product."""
    product = Product.query.get_or_404(product_id)
    product_name = product.name
    
    try:
        db.session.delete(product)
        db.session.commit()
        flash(f'Product "{product_name}" deleted successfully!', 'success')
    except Exception as e:
        db.session.rollback()
        flash('An error occurred while deleting the product. Please try again.', 'error')
    
    return redirect(url_for('admin.dashboard'))


# ============ Order Management Routes ============

@admin_bp.route('/orders')
@admin_required
def orders():
    """View all orders."""
    all_orders = Order.query.order_by(Order.created_at.desc()).all()
    return render_template('admin/orders.html', orders=all_orders)


@admin_bp.route('/order/<int:order_id>')
@admin_required
def order_detail(order_id):
    """View order details."""
    order = Order.query.get_or_404(order_id)
    return render_template('admin/order_detail.html', order=order)


@admin_bp.route('/order/update-status/<int:order_id>', methods=['POST'])
@admin_required
def update_order_status(order_id):
    """Update order status."""
    order = Order.query.get_or_404(order_id)
    new_status = request.form.get('status')
    
    if new_status in ['pending', 'processing', 'completed', 'cancelled']:
        order.status = new_status
        db.session.commit()
        flash(f'Order #{order.id} status updated to {new_status}', 'success')
    else:
        flash('Invalid status.', 'error')
    
    return redirect(url_for('admin.order_detail', order_id=order_id))


@admin_bp.route('/order/delete/<int:order_id>', methods=['POST'])
@admin_required
def delete_order(order_id):
    """Delete/complete an order (remove from active list)."""
    order = Order.query.get_or_404(order_id)
    order_id_num = order.id
    
    try:
        db.session.delete(order)
        db.session.commit()
        flash(f'Order #{order_id_num} has been removed.', 'success')
    except Exception as e:
        db.session.rollback()
        flash('An error occurred while removing the order.', 'error')
    
    return redirect(url_for('admin.orders'))