"""Owner-only licence issuer. Run separately from the customer POS installation."""
import base64
import json
import os
from datetime import datetime, timedelta

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from flask import Flask, flash, redirect, render_template_string, request, url_for

PORTAL_DIR = os.path.dirname(os.path.abspath(__file__))
PRIVATE_KEY_PATH = os.environ.get("POS_LICENSE_PRIVATE_KEY", os.path.join(PORTAL_DIR, "license_private_key.pem"))
PUBLIC_KEY_PATH = os.path.join(PORTAL_DIR, "license_public_key.pem")
PORTAL_PASSWORD = os.environ.get("POS_PORTAL_PASSWORD")

app = Flask(__name__)
app.secret_key = os.environ.get("POS_PORTAL_SECRET", os.urandom(32))


def issuer_key():
    if os.path.exists(PRIVATE_KEY_PATH):
        with open(PRIVATE_KEY_PATH, "rb") as handle:
            key = serialization.load_pem_private_key(handle.read(), password=None)
        if not os.path.exists(PUBLIC_KEY_PATH):
            with open(PUBLIC_KEY_PATH, "wb") as handle:
                handle.write(key.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo))
        return key
    key = Ed25519PrivateKey.generate()
    with open(PRIVATE_KEY_PATH, "wb") as handle:
        handle.write(key.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.NoEncryption()))
    with open(PUBLIC_KEY_PATH, "wb") as handle:
        handle.write(key.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo))
    return key


PAGE = """<!doctype html><title>POS Licence Issuer</title><style>body{font-family:Arial;max-width:620px;margin:40px auto;padding:0 16px}input,textarea,button{width:100%;box-sizing:border-box;padding:10px;margin:6px 0}textarea{height:100px}button{background:#14532d;color:white;border:0;border-radius:6px}.help{background:#eff6ff;border-left:4px solid #2563eb;padding:12px;line-height:1.5}.error{color:#b91c1c}</style><h2>POS Licence Issuer</h2><p>Keep this page and its private key only with the owner.</p><div class=help><b>How to create a key:</b><ol><li>Open the customer POS: <code>http://127.0.0.1:5000/activation</code>.</li><li>Copy the complete code beginning with <code>POS1.</code>.</li><li>Paste it below, then enter the shop name and licence duration.</li></ol></div>{% for c,m in get_flashed_messages(with_categories=true) %}<p class=error>{{m}}</p>{% endfor %}<form method=post><label>Portal password</label><input type=password name=password required><label>Activation request code</label><textarea name=request_code required placeholder="Paste the full POS1.... code here"></textarea><label>Customer/shop name</label><input name=shop_name required><label>Licence days</label><input type=number name=days value=365 min=1 required><button>Create activation key</button></form>{% if token %}<h3>Activation key</h3><textarea readonly>{{token}}</textarea><p>Copy this full key to the customer POS activation page.</p>{% endif %}"""


@app.route("/", methods=["GET", "POST"])
def issue():
    token = None
    if request.method == "POST":
        if not PORTAL_PASSWORD or request.form.get("password") != PORTAL_PASSWORD:
            flash("Invalid portal password.", "danger")
            return render_template_string(PAGE)
        parts = request.form["request_code"].strip().split(".")
        if len(parts) != 3 or parts[0] != "POS1" or not parts[1] or not parts[2]:
            flash("Paste the complete request code from POS Activation. It must begin with POS1.", "danger")
            return render_template_string(PAGE)
        payload = {"installation_id": parts[1], "device_hash": parts[2], "shop_name": request.form["shop_name"].strip(), "issued_at": datetime.utcnow().isoformat(), "expires_at": (datetime.utcnow() + timedelta(days=int(request.form["days"]))).isoformat()}
        raw = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
        signature = issuer_key().sign(raw)
        token = base64.urlsafe_b64encode(raw).decode().rstrip("=") + "." + base64.urlsafe_b64encode(signature).decode().rstrip("=")
    return render_template_string(PAGE, token=token)


if __name__ == "__main__":
    if not PORTAL_PASSWORD:
        raise SystemExit("Set POS_PORTAL_PASSWORD before starting the licence portal.")
    issuer_key()
    app.run(host="127.0.0.1", port=5050, debug=False)
