from flask import Flask, render_template, request, jsonify, redirect, url_for, session
from functools import wraps
import os
import json
import traceback
from config import Config
from modules.wordpress import WordPressConnector
from modules.gemini_ai import GeminiWriter
from modules.google_gsc import GSCConnector
from modules.google_ga4 import GA4Connector
from modules.bing_webmaster import BingConnector
from modules.seo_analyzer import SEOAuditor

app = Flask(__name__)
app.secret_key = os.urandom(24)

# Load config
config = Config()


# -----------------------------------------------------------------
# Simple authentication decorator using TOOL_SECRET
# -----------------------------------------------------------------
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not session.get("authenticated"):
            if request.is_json:
                return jsonify({"error": "Unauthorized"}), 401
            return redirect(url_for("login"))
        return f(*args, **kwargs)
    return decorated_function


# -----------------------------------------------------------------
# Auth routes
# -----------------------------------------------------------------
@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        secret = request.form.get("secret", "")
        if secret == config.TOOL_SECRET:
            session["authenticated"] = True
            return redirect(url_for("dashboard"))
        return render_template("login.html", error="Invalid password. Try again.")
    return render_template("login.html", error=None)


@app.route("/logout")
def logout():
    session.clear()
    return redirect(url_for("login"))


# -----------------------------------------------------------------
# Page routes
# -----------------------------------------------------------------
@app.route("/")
@login_required
def dashboard():
    return render_template("dashboard.html")


@app.route("/generate")
@login_required
def generate():
    return render_template("generate.html")


@app.route("/analytics")
@login_required
def analytics():
    return render_template("analytics.html")


@app.route("/seo-audit")
@login_required
def seo_audit():
    return render_template("seo_audit.html")


@app.route("/settings")
@login_required
def settings():
    return render_template("settings.html", config=config)


# -----------------------------------------------------------------
# API: Generate blog post via Gemini AI
# -----------------------------------------------------------------
@app.route("/api/generate", methods=["POST"])
@login_required
def api_generate():
    try:
        data = request.get_json()
        keyword = data.get("keyword", "")
        tone = data.get("tone", "professional")
        word_count = int(data.get("word_count", 2000))

        if not keyword:
            return jsonify({"error": "Keyword is required"}), 400

        if not config.GEMINI_API_KEY:
            return jsonify({"error": "Gemini API key not configured. Go to Settings."}), 400

        writer = GeminiWriter(config.GEMINI_API_KEY)
        result = writer.generate_blog_post(keyword, tone=tone, word_count=word_count)
        return jsonify({"success": True, "data": result})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


# -----------------------------------------------------------------
# API: Publish to WordPress
# -----------------------------------------------------------------
@app.route("/api/publish", methods=["POST"])
@login_required
def api_publish():
    try:
        data = request.get_json()

        if not all([config.WP_URL, config.WP_USER, config.WP_APP_PASSWORD]):
            return jsonify({"error": "WordPress not configured. Go to Settings."}), 400

        wp = WordPressConnector(config.WP_URL, config.WP_USER, config.WP_APP_PASSWORD)

        # Get or create categories and tags
        category_ids = []
        if data.get("category"):
            cat_id = wp.get_or_create_category(data["category"])
            if cat_id:
                category_ids.append(cat_id)

        tag_ids = []
        for tag_name in data.get("tags", []):
            tag_id = wp.get_or_create_tag(tag_name)
            if tag_id:
                tag_ids.append(tag_id)

        result = wp.publish_post(
            title=data.get("title", "Untitled"),
            content_html=data.get("content_html", ""),
            status=data.get("status", "draft"),
            categories=category_ids,
            tags=tag_ids,
            meta_description=data.get("meta_description", ""),
            focus_keyword=data.get("focus_keyword", ""),
            slug=data.get("slug", ""),
        )
        return jsonify({"success": True, "data": result})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


# -----------------------------------------------------------------
# API: Fetch analytics data
# -----------------------------------------------------------------
@app.route("/api/analytics/gsc", methods=["POST"])
@login_required
def api_analytics_gsc():
    try:
        data = request.get_json() or {}
        days = int(data.get("days", 30))

        if not all([config.GOOGLE_APPLICATION_CREDENTIALS, config.GSC_SITE_URL]):
            return jsonify({"error": "Google Search Console not configured."}), 400

        gsc = GSCConnector(config.GOOGLE_APPLICATION_CREDENTIALS, config.GSC_SITE_URL)
        result = {
            "top_queries": gsc.get_top_queries(days=days),
            "top_pages": gsc.get_top_pages(days=days),
            "low_hanging_fruit": gsc.get_low_hanging_fruit(days=days),
        }
        return jsonify({"success": True, "data": result})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


@app.route("/api/analytics/ga4", methods=["POST"])
@login_required
def api_analytics_ga4():
    try:
        data = request.get_json() or {}
        days = int(data.get("days", 30))

        if not all([config.GOOGLE_APPLICATION_CREDENTIALS, config.GA4_PROPERTY_ID]):
            return jsonify({"error": "Google Analytics not configured."}), 400

        ga4 = GA4Connector(config.GOOGLE_APPLICATION_CREDENTIALS, config.GA4_PROPERTY_ID)
        result = {
            "overview": ga4.get_overview(days=days),
            "traffic_sources": ga4.get_traffic_sources(days=days),
            "top_pages": ga4.get_top_pages(days=days),
        }
        return jsonify({"success": True, "data": result})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


@app.route("/api/analytics/bing", methods=["POST"])
@login_required
def api_analytics_bing():
    try:
        data = request.get_json() or {}

        if not all([config.BING_API_KEY, config.BING_SITE_URL]):
            return jsonify({"error": "Bing Webmaster not configured."}), 400

        bing = BingConnector(config.BING_API_KEY, config.BING_SITE_URL)
        result = {
            "query_stats": bing.get_query_stats(),
            "page_stats": bing.get_page_stats(),
            "crawl_stats": bing.get_crawl_stats(),
        }
        return jsonify({"success": True, "data": result})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


# -----------------------------------------------------------------
# API: SEO Audit
# -----------------------------------------------------------------
@app.route("/api/seo-audit/run", methods=["POST"])
@login_required
def api_seo_audit_run():
    try:
        data = request.get_json() or {}
        url = data.get("url", "")
        audit_full = data.get("audit_full", False)

        if not url and not config.WP_URL:
            return jsonify({"error": "No URL provided and WordPress URL not configured."}), 400

        site_url = url or config.WP_URL
        auditor = SEOAuditor(site_url)

        if audit_full:
            results = auditor.audit_site()
        else:
            results = [auditor.audit_page(site_url)]

        return jsonify({"success": True, "data": results})

    except Exception as e:
        return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500


# -----------------------------------------------------------------
# API: Settings
# -----------------------------------------------------------------
@app.route("/api/settings/test-wp", methods=["POST"])
@login_required
def api_test_wp():
    try:
        data = request.get_json()
        wp = WordPressConnector(
            data.get("wp_url", ""),
            data.get("wp_user", ""),
            data.get("wp_app_password", ""),
        )
        connected = wp.test_connection()
        return jsonify({"success": connected, "message": "Connected!" if connected else "Connection failed."})

    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500


@app.route("/api/settings/save", methods=["POST"])
@login_required
def api_save_settings():
    try:
        data = request.get_json()
        env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")

        lines = []
        key_map = {
            "wp_url": "WP_URL",
            "wp_user": "WP_USER",
            "wp_app_password": "WP_APP_PASSWORD",
            "gemini_api_key": "GEMINI_API_KEY",
            "groq_api_key": "GROQ_API_KEY",
            "google_credentials": "GOOGLE_APPLICATION_CREDENTIALS",
            "ga4_property_id": "GA4_PROPERTY_ID",
            "gsc_site_url": "GSC_SITE_URL",
            "bing_api_key": "BING_API_KEY",
            "bing_site_url": "BING_SITE_URL",
            "indexnow_key": "INDEXNOW_KEY",
        }

        # Read existing .env
        existing = {}
        if os.path.exists(env_path):
            with open(env_path, "r") as ef:
                for line in ef:
                    line = line.strip()
                    if "=" in line and not line.startswith("#"):
                        k, v = line.split("=", 1)
                        existing[k.strip()] = v.strip()

        # Update with new values
        for form_key, env_key in key_map.items():
            if form_key in data and data[form_key]:
                existing[env_key] = data[form_key]

        # Preserve TOOL_SECRET
        if "TOOL_SECRET" not in existing:
            existing["TOOL_SECRET"] = config.TOOL_SECRET or "changeme"

        # Write .env
        with open(env_path, "w") as ef:
            for k, v in existing.items():
                ef.write(f"{k}={v}\n")

        # Reload config
        config.reload()

        return jsonify({"success": True, "message": "Settings saved! Reload the page to apply."})

    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500


# -----------------------------------------------------------------
# Run the app (for local development only)
# -----------------------------------------------------------------
if __name__ == "__main__":
    app.run(debug=True, port=5000)
