from __future__ import annotations
import jwt

import os
import logging
from logging.handlers import RotatingFileHandler
from flask import Flask, request, jsonify
from flask_cors import CORS
from flask import Response
from werkzeug.middleware.proxy_fix import ProxyFix

try:
    from dotenv import load_dotenv
    load_dotenv()
except Exception:
    pass

from helpers.netopia import verify_ipn, get_status

app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "*"}})

# Tell Flask it is behind a proxy and should trust the X-Forwarded headers
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)

# ---------- Logging ----------
app.logger.setLevel(logging.INFO)
_log_dir = os.getenv("LOG_DIR", "logs")
os.makedirs(_log_dir, exist_ok=True)
_handler = RotatingFileHandler(os.path.join(_log_dir, "netopia_api.log"), maxBytes=1_000_000, backupCount=3)
_handler.setLevel(logging.INFO)
_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(message)s"))
app.logger.addHandler(_handler)


@app.get("/healthz")
def healthz():
    return {"ok": True}, 200

@app.post("/api/payments/ipn")
def ipn():
    try:
        
        # Pass the whole request object, not just request.data
        data = verify_ipn(request.data) 

        app.logger.info("IPN OK: %s", data)
        return jsonify({"errorCode": 0}), 200
    except Exception as e:
        app.logger.exception("IPN verification failed: %s", e)
        return jsonify({"errorCode": 0}), 200
    

# @app.post("/api/payments/ipn")
# def ipn():
#     token = request.headers.get('Verification-Token') or request.headers.get('X-Netopia-Signature')
    
#     try:
#         from helpers.netopia import NetopiaSettings
#         settings = NetopiaSettings.from_env()
#         public_key = settings.public_key_str.replace('\\n', '\n').strip()
        
#         # 1. Try to decode without Audience check first to isolate the Signature
#         # This tells us if the Public Key actually matches the Private Key used by Netopia
#         decoded_data = jwt.decode(
#             token, 
#             public_key, 
#             algorithms=["RS256", "RS512"], 
#             options={"verify_aud": False}, # Temporarily disable audience check
#             leeway=60
#         )
        
#         app.logger.info(f"SUCCESS! Verified Data: {decoded_data}")
        
#         # 2. Check audience manually
#         token_aud = decoded_data.get('aud')
#         expected_aud = settings.pos_signature
        
#         # Netopia sends ['SIG'], we expect 'SIG'
#         if expected_aud not in token_aud and expected_aud != token_aud:
#             app.logger.error(f"Audience mismatch: Got {token_aud}, expected {expected_aud}")
#             return jsonify({"error": "Audience mismatch"}), 400

#         return jsonify({"errorCode": 0}), 200

#     except jwt.InvalidSignatureError:
#         app.logger.error("DANGER: The Public Key does not match the signature. Check if this is the SANDBOX key.")
#         return jsonify({"error": "Invalid Signature"}), 400
#     except Exception as e:
#         app.logger.error(f"Verification Failed: {type(e).__name__} - {e}")
#         return jsonify({"error": str(e)}), 400


@app.get("/api/payments/status")
def status():
    ntp_id = request.args.get("ntpID")
    order_id = request.args.get("orderID")
    try:
        resp = get_status(ntp_id=ntp_id, order_id=order_id)
        return jsonify({"ok": True, "data": resp}), 200
    except Exception as e:
        app.logger.exception("Status query failed: %s", e)
        return jsonify({"ok": False, "error": str(e)}), 400


if __name__ == "__main__":
    host = os.getenv("API_HOST", "0.0.0.0")
    port = int(os.getenv("API_PORT", "9000"))
    app.logger.info("Starting NETOPIA Flask sidecar on %s:%s", host, port)
    app.run(host=host, port=port)
