from flask import Blueprint, render_template, redirect, url_for, session, flash, request
from extensions import db
from models import Product, ProductVariant, Category, StockMovement


stock_bp = Blueprint("stock", __name__)


# =========================================================
# STOCK OVERVIEW
# =========================================================

@stock_bp.route("/admin/stock", methods=["GET"])
def admin_stock():

    if "user_id" not in session:
        return redirect(url_for("auth.login"))

    if session.get("role") not in ["owner", "admin"]:
        flash(
            "You do not have permission to view stock.",
            "error"
        )
        return redirect(
            url_for("dashboard.admin_dashboard")
        )

    search = request.args.get(
        "search",
        ""
    ).strip()

    category_id = request.args.get(
        "category_id",
        ""
    ).strip()

    stock_status = request.args.get(
        "stock_status",
        ""
    ).strip()

    query = (
        ProductVariant.query
        .join(Product)
    )

    # -----------------------------------------------------
    # SEARCH
    # -----------------------------------------------------

    if search:

        query = query.filter(
            db.or_(
                Product.name.ilike(
                    f"%{search}%"
                ),
                ProductVariant.sku.ilike(
                    f"%{search}%"
                ),
                ProductVariant.mass.ilike(
                    f"%{search}%"
                )
            )
        )

    # -----------------------------------------------------
    # CATEGORY
    # -----------------------------------------------------

    if category_id:

        try:

            category_id_value = int(
                category_id
            )

            query = query.filter(
                Product.category_id == category_id_value
            )

        except ValueError:

            category_id = ""

    # -----------------------------------------------------
    # STOCK STATUS
    # -----------------------------------------------------

    if stock_status == "out":

        query = query.filter(
            ProductVariant.stock_quantity <= 0
        )

    elif stock_status == "low":

        query = query.filter(
            ProductVariant.stock_quantity > 0,
            ProductVariant.stock_quantity <= 10
        )

    elif stock_status == "in":

        query = query.filter(
            ProductVariant.stock_quantity > 10
        )

    variants = (
        query
        .order_by(
            Product.name.asc(),
            ProductVariant.price.asc()
        )
        .all()
    )

    # -----------------------------------------------------
    # CATEGORIES
    # -----------------------------------------------------

    categories = (
        Category.query
        .filter_by(is_active=True)
        .order_by(Category.name.asc())
        .all()
    )

    # -----------------------------------------------------
    # SUMMARY COUNTS
    # -----------------------------------------------------

    all_variants = ProductVariant.query.all()

    total_variants = len(
        all_variants
    )

    total_stock = sum(
        variant.stock_quantity or 0
        for variant in all_variants
    )

    low_stock = sum(
        1
        for variant in all_variants
        if 0 < (variant.stock_quantity or 0) <= 10
    )

    out_of_stock = sum(
        1
        for variant in all_variants
        if (variant.stock_quantity or 0) <= 0
    )

    return render_template(
        "admin/stock.html",
        variants=variants,
        categories=categories,
        total_variants=total_variants,
        total_stock=total_stock,
        low_stock=low_stock,
        out_of_stock=out_of_stock,
        search=search,
        category_id=category_id,
        stock_status=stock_status
    )


# =========================================================
# ADJUST STOCK
# =========================================================

@stock_bp.route(
    "/admin/stock/<int:variant_id>/adjust",
    methods=["POST"]
)
def adjust_stock(variant_id):

    if "user_id" not in session:
        return redirect(url_for("auth.login"))

    if session.get("role") not in ["owner", "admin"]:
        flash(
            "You do not have permission to adjust stock.",
            "error"
        )
        return redirect(
            url_for("dashboard.admin_dashboard")
        )

    variant = db.session.get(
        ProductVariant,
        variant_id
    )

    if not variant:

        flash(
            "Stock item not found.",
            "error"
        )

        return redirect(
            url_for("stock.admin_stock")
        )

    adjustment = request.form.get(
        "adjustment",
        ""
    ).strip()

    reason = request.form.get(
        "reason",
        ""
    ).strip()

    try:

        adjustment_value = int(
            adjustment
        )

    except ValueError:

        flash(
            "Stock adjustment must be a whole number.",
            "error"
        )

        return redirect(
            url_for("stock.admin_stock")
        )

    if adjustment_value == 0:

        flash(
            "Stock adjustment cannot be zero.",
            "error"
        )

        return redirect(
            url_for("stock.admin_stock")
        )

    current_stock = (
        variant.stock_quantity or 0
    )

    new_stock = (
        current_stock + adjustment_value
    )

    if new_stock < 0:

        flash(
            "Stock cannot be reduced below zero.",
            "error"
        )

        return redirect(
            url_for("stock.admin_stock")
        )

    # -----------------------------------------------------
    # UPDATE STOCK
    # -----------------------------------------------------

    variant.stock_quantity = new_stock

    if new_stock == 0:
        variant.is_available = False

    elif current_stock == 0 and new_stock > 0:
        variant.is_available = True

    # -----------------------------------------------------
    # RECORD MOVEMENT
    # -----------------------------------------------------

    if adjustment_value > 0:

        movement_type = "adjustment_in"

    else:

        movement_type = "adjustment_out"

    movement = StockMovement(
        variant_id=variant.id,
        quantity=adjustment_value,
        movement_type=movement_type,
        reference=reason or "Manual stock adjustment"
    )

    db.session.add(
        movement
    )

    try:

        db.session.commit()

    except Exception:

        db.session.rollback()

        flash(
            "The stock adjustment could not be saved.",
            "error"
        )

        return redirect(
            url_for("stock.admin_stock")
        )

    flash(
        "Stock adjusted successfully.",
        "success"
    )

    return redirect(
        url_for("stock.admin_stock")
    )