"""Flask API server for Lead Generation & Tech Scoping Engine."""
from __future__ import annotations
import json
import logging
import os
import sys
from pathlib import Path

import httpx
from flask import Flask, request, jsonify

from models import CompanyTechProfile, LeadGenRequest, LeadGenResponse
from engine import LeadScopingEngine

# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    stream=sys.stdout,
)
logger = logging.getLogger("leadgen")

# ---------------------------------------------------------------------------
# Config file
# ---------------------------------------------------------------------------
CONFIG_PATH = Path(os.getenv("LEADGEN_CONFIG", "/app/data/leadgen_config.json"))
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)

DEFAULT_CONFIG = {
    "api_key": os.getenv("DEEPSEEK_API_KEY", ""),
    "base_url": "https://openrouter.ai/api/v1",
    "model": "qwen/qwen3-coder:free",
    "fallback_models": [
        "meta-llama/llama-3.3-70b-instruct:free",
        "google/gemma-4-26b-a4b-it:free",
        "nvidia/nemotron-3-super-120b-a12b:free",
    ],
}


def load_config() -> dict:
    if CONFIG_PATH.exists():
        try:
            return json.loads(CONFIG_PATH.read_text())
        except Exception:
            pass
    cfg = dict(DEFAULT_CONFIG)
    save_config(cfg)
    return cfg


def save_config(cfg: dict) -> None:
    CONFIG_PATH.write_text(json.dumps(cfg, indent=2))


config = load_config()

# ---------------------------------------------------------------------------
# App
# ---------------------------------------------------------------------------
app = Flask(__name__)


def get_engine() -> LeadScopingEngine:
    cfg = load_config()
    return LeadScopingEngine(
        api_key=cfg.get("api_key"),
        api_base=cfg.get("base_url"),
    )


@app.route("/python-leadgen/", methods=["GET"])
def index():
    return jsonify({
        "service": "Mek-Tech Lead Generation & Tech Scoping Engine",
        "version": "2.0",
        "endpoints": {
            "GET  /python-leadgen/config": "Get current config (model, base_url, key masked)",
            "POST /python-leadgen/config": "Update config",
            "GET  /python-leadgen/models": "List available free models from configured API",
            "POST /python-leadgen/analyze": "Analyze a single URL",
            "POST /python-leadgen/batch": "Analyze multiple URLs",
            "GET  /python-leadgen/health": "Health check",
        },
    })


@app.route("/python-leadgen/health", methods=["GET"])
def health():
    cfg = load_config()
    return jsonify({
        "status": "healthy",
        "api_configured": bool(cfg.get("api_key")),
        "model": cfg.get("model"),
        "base_url": cfg.get("base_url"),
    })


@app.route("/python-leadgen/config", methods=["GET"])
def get_config():
    cfg = load_config()
    key = cfg.get("api_key", "")
    return jsonify({
        "base_url": cfg.get("base_url"),
        "model": cfg.get("model"),
        "fallback_models": cfg.get("fallback_models", []),
        "api_key_set": bool(key),
        "api_key_preview": (key[:12] + "..." + key[-4:]) if len(key) > 16 else ("***" if key else ""),
    })


@app.route("/python-leadgen/config", methods=["POST"])
def set_config():
    try:
        body = request.get_json(silent=True) or {}
    except Exception:
        return jsonify({"success": False, "error": "Invalid JSON"}), 400

    cfg = load_config()
    if "api_key" in body and body["api_key"]:
        cfg["api_key"] = body["api_key"]
    if "base_url" in body:
        cfg["base_url"] = body["base_url"]
    if "model" in body:
        cfg["model"] = body["model"]
    if "fallback_models" in body:
        cfg["fallback_models"] = body["fallback_models"]

    save_config(cfg)
    logger.info("Config updated: model=%s base_url=%s", cfg.get("model"), cfg.get("base_url"))
    return jsonify({"success": True, "model": cfg["model"]})


@app.route("/python-leadgen/models", methods=["GET"])
async def list_models():
    """Fetch available free models from the configured API endpoint."""
    cfg = load_config()
    base = cfg.get("base_url", "https://openrouter.ai/api/v1")
    key = cfg.get("api_key", "")

    models_url = base.rstrip("/") + "/models"

    try:
        async with httpx.AsyncClient(timeout=15) as client:
            resp = await client.get(
                models_url,
                headers={"Authorization": f"Bearer {key}"} if key else {},
            )
            if resp.status_code != 200:
                return jsonify({
                    "success": False,
                    "error": f"API returned {resp.status_code}",
                    "models": _fallback_model_list(),
                })

            data = resp.json()
            all_models = data.get("data", [])

            free_models = [
                {
                    "id": m["id"],
                    "name": m.get("name", m["id"]),
                    "context_length": m.get("context_length", 0),
                    "pricing": str(m.get("pricing", {})),
                }
                for m in all_models
                if ":free" in m.get("id", "")
            ]
            free_models.sort(key=lambda m: -m["context_length"])

            return jsonify({"success": True, "total": len(free_models), "models": free_models})

    except Exception as e:
        return jsonify({
            "success": False,
            "error": str(e),
            "models": _fallback_model_list(),
        })


def _fallback_model_list():
    return [
        {"id": "qwen/qwen3-coder:free", "name": "Qwen 3 Coder (Free)", "context_length": 1048576},
        {"id": "google/gemma-4-31b-it:free", "name": "Gemma 4 31B (Free)", "context_length": 262144},
        {"id": "google/gemma-4-26b-a4b-it:free", "name": "Gemma 4 26B (Free)", "context_length": 262144},
        {"id": "meta-llama/llama-3.3-70b-instruct:free", "name": "Llama 3.3 70B (Free)", "context_length": 131072},
        {"id": "nvidia/nemotron-3-super-120b-a12b:free", "name": "Nemotron Super 120B (Free)", "context_length": 1000000},
    ]


@app.route("/python-leadgen/analyze", methods=["POST"])
async def analyze():
    try:
        body = request.get_json(silent=True) or {}
    except Exception:
        return jsonify({"success": False, "error": "Invalid JSON body"}), 400

    url = body.get("url", "").strip()
    if not url:
        return jsonify({"success": False, "error": "Missing required field: url"}), 400

    engine = get_engine()
    try:
        result: LeadGenResponse = await engine.analyze_url(url)
    except Exception as exc:
        logger.exception("Unexpected error analyzing %s", url)
        return jsonify({"success": False, "error": str(exc)}), 500

    if result.success and result.profile:
        return jsonify(result.model_dump())
    else:
        return jsonify(result.model_dump()), 422


@app.route("/python-leadgen/batch", methods=["POST"])
async def batch():
    try:
        body = request.get_json(silent=True) or {}
    except Exception:
        return jsonify({"success": False, "error": "Invalid JSON body"}), 400

    urls = body.get("urls", [])
    if not urls or not isinstance(urls, list):
        return jsonify({"success": False, "error": "Missing required field: urls (list)"}), 400

    if len(urls) > 10:
        return jsonify({"success": False, "error": "Maximum 10 URLs per batch"}), 400

    engine = get_engine()
    try:
        results = await engine.batch_analyze(urls)
    except Exception as exc:
        logger.exception("Batch analysis failed")
        return jsonify({"success": False, "error": str(exc)}), 500

    return jsonify({
        "success": True,
        "total": len(urls),
        "results": [r.model_dump() for r in results],
    })


if __name__ == "__main__":
    port = int(os.getenv("LEADGEN_PORT", "3003"))
    debug = os.getenv("LEADGEN_DEBUG", "0") == "1"
    app.run(host="0.0.0.0", port=port, debug=debug)
