"""The web app for Tutorial 3: a small inventory lookup tool.

Start it with:

    python app.py

Then open http://127.0.0.1:5000 in your browser.

This file only deals with web pages: which address shows which page, what
the form sends, and which template to draw. All the actual inventory work
(loading, searching, changing a number) lives in inventory.py.
"""

from flask import Flask, redirect, render_template, request, url_for

# Import our own helper functions from inventory.py, the file next to this one.
from inventory import (
    adjust_quantity,
    count_low_stock,
    load_items,
    save_items,
    search_items,
)

# This creates the application. __name__ tells Flask where this file is, so
# it can find the templates/ and static/ folders beside it.
app = Flask(__name__)


@app.route("/")
def home():
    """The home page: show every item in the inventory.

    @app.route("/") means: when a browser asks for the address "/", run
    this function. Whatever the function returns is what the browser shows.
    """
    items = load_items()

    # render_template finds templates/index.html, fills in the values we
    # pass, and returns finished HTML.
    return render_template(
        "index.html",
        items=items,
        total_items=len(items),
        low_stock=count_low_stock(items),
    )


@app.route("/search")
def search():
    """The search results page.

    The search box sends what you typed in the web address, like
    /search?q=coffee. request.args is how Flask hands us that value.
    The second argument to .get() is the default if nothing was sent.
    """
    query = request.args.get("q", "")
    message = request.args.get("message", "")

    items = load_items()
    matches = search_items(items, query)

    return render_template(
        "search.html",
        query=query,
        matches=matches,
        match_count=len(matches),
        message=message,
    )


@app.route("/adjust", methods=["POST"])
def adjust():
    """Add to or subtract from one item's quantity.

    methods=["POST"] means this address only accepts a submitted form, not
    a plain visit. Values typed into a POST form arrive in request.form.
    """
    sku = request.form.get("sku", "")
    change_text = request.form.get("change", "0")

    # Everything from a form arrives as text, so "5" must become the
    # number 5. If the person typed something that is not a number, we say
    # so instead of crashing.
    try:
        change = int(change_text)
    except ValueError:
        message = "'" + change_text + "' is not a whole number."
        return redirect(url_for("search", q=sku, message=message))

    items = load_items()
    item, message = adjust_quantity(items, sku, change)

    # Only write the file back if we actually changed something.
    if item is not None:
        save_items(items)

    # After a successful form submit we send the browser to a normal page.
    # That way a refresh does not submit the same change twice.
    return redirect(url_for("search", q=sku, message=message))


if __name__ == "__main__":
    # debug=True restarts the server when you save a file and shows a
    # helpful error page. Use it while learning, not on a real server.
    app.run(debug=True)
