"""Form Actions API — CRUD endpoints for managing post-submission actions.

Each site can have multiple actions (webhook, email, log, redirect, document).
Actions are executed in execution_order after each submission.
"""

from flask import Blueprint, jsonify, request

from app.models import (
    TIERS,
    create_action,
    delete_action,
    get_action,
    get_actions_by_site,
    get_site,
    toggle_action,
    update_action,
)
from app.routes.auth import current_user, login_required

actions_bp = Blueprint("actions", __name__)

VALID_ACTION_TYPES = {"webhook", "email", "log", "redirect", "document", "chain"}


@actions_bp.route("/sites/<int:site_id>/actions", methods=["GET"])
@login_required
def list_actions(site_id):
    """List all actions for a site."""
    site = get_site(site_id)
    if not site:
        return jsonify({"error": "Site not found"}), 404

    # Verify ownership
    user = current_user()
    if not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    actions = get_actions_by_site(site_id)
    return jsonify({"actions": actions}), 200


@actions_bp.route("/sites/<int:site_id>/actions", methods=["POST"])
@login_required
def create_new_action(site_id):
    """Create a new action for a site."""
    site = get_site(site_id)
    if not site:
        return jsonify({"error": "Site not found"}), 404

    user = current_user()
    if not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    data = request.get_json(force=True)
    action_type = data.get("type", "").lower()
    if action_type not in VALID_ACTION_TYPES:
        return jsonify({"error": f"Invalid action type. Must be one of: {', '.join(sorted(VALID_ACTION_TYPES))}"}), 400

    # Check tier limits for chain actions
    if action_type == "chain":
        from app.models import check_chain_quota

        allowed, current_count, max_chains = check_chain_quota(user["id"])
        if not allowed:
            tier_config = TIERS.get(user.get("tier", "free"), TIERS["free"])
            if max_chains == 0:
                return jsonify(
                    {
                        "error": "Action chains are not available on your current plan",
                        "upgrade_required": True,
                        "current_tier": user.get("tier", "free"),
                    }
                ), 403
            return jsonify(
                {
                    "error": f"Action chain limit reached ({current_count}/{max_chains})",
                    "upgrade_required": True,
                    "current_count": current_count,
                    "max_chains": max_chains,
                    "current_tier": user.get("tier", "free"),
                }
            ), 403

    config = data.get("config", {})
    trigger_event = data.get("trigger_event", "submission")
    enabled = data.get("enabled", True)
    execution_order = data.get("execution_order", 0)

    # Validate config has required fields per type
    if action_type == "webhook" and not config.get("url"):
        return jsonify({"error": "Webhook action requires 'url' in config"}), 400
    if action_type == "email" and not config.get("recipients"):
        return jsonify({"error": "Email action requires 'recipients' in config"}), 400
    if action_type == "redirect" and not config.get("url"):
        return jsonify({"error": "Redirect action requires 'url' in config"}), 400
    if action_type == "document" and not config.get("template_id"):
        return jsonify({"error": "Document action requires 'template_id' in config"}), 400
    if action_type == "chain":
        from app.services.chain_engine import validate_chain

        validation = validate_chain(config)
        if not validation["valid"]:
            return jsonify({"error": "Invalid chain", "details": validation["errors"]}), 400

    action_id = create_action(
        site_id=site_id,
        action_type=action_type,
        config=config,
        trigger_event=trigger_event,
        enabled=enabled,
        execution_order=execution_order,
    )

    action = get_action(action_id)
    return jsonify({"action": action}), 201


@actions_bp.route("/actions/<int:action_id>", methods=["GET"])
@login_required
def get_action_endpoint(action_id):
    """Get a single action by ID."""
    action = get_action(action_id)
    if not action:
        return jsonify({"error": "Action not found"}), 404

    # Verify ownership via site
    user = current_user()
    site = get_site(action["site_id"])
    if not site or not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    return jsonify({"action": action}), 200


@actions_bp.route("/actions/<int:action_id>", methods=["PUT"])
@login_required
def update_action_endpoint(action_id):
    """Update an existing action."""
    action = get_action(action_id)
    if not action:
        return jsonify({"error": "Action not found"}), 404

    user = current_user()
    site = get_site(action["site_id"])
    if not site or not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    data = request.get_json(force=True)

    # Validate type if changing
    if "type" in data:
        new_type = data["type"].lower()
        if new_type not in VALID_ACTION_TYPES:
            return jsonify(
                {"error": f"Invalid action type. Must be one of: {', '.join(sorted(VALID_ACTION_TYPES))}"}
            ), 400

    # Validate config if changing type
    action_type = data.get("type", action["type"])
    config = data.get("config", action.get("config", {}))
    if action_type == "webhook" and not config.get("url"):
        return jsonify({"error": "Webhook action requires 'url' in config"}), 400
    if action_type == "email" and not config.get("recipients"):
        return jsonify({"error": "Email action requires 'recipients' in config"}), 400
    if action_type == "redirect" and not config.get("url"):
        return jsonify({"error": "Redirect action requires 'url' in config"}), 400
    if action_type == "document" and not config.get("template_id"):
        return jsonify({"error": "Document action requires 'template_id' in config"}), 400
    if action_type == "chain":
        from app.services.chain_engine import validate_chain

        validation = validate_chain(config)
        if not validation["valid"]:
            return jsonify({"error": "Invalid chain", "details": validation["errors"]}), 400

    update_action(action_id, **data)
    updated = get_action(action_id)
    return jsonify({"action": updated}), 200


@actions_bp.route("/actions/<int:action_id>", methods=["DELETE"])
@login_required
def delete_action_endpoint(action_id):
    """Delete an action."""
    action = get_action(action_id)
    if not action:
        return jsonify({"error": "Action not found"}), 404

    user = current_user()
    site = get_site(action["site_id"])
    if not site or not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    delete_action(action_id)
    return jsonify({"success": True}), 200


@actions_bp.route("/actions/<int:action_id>/toggle", methods=["POST"])
@login_required
def toggle_action_endpoint(action_id):
    """Toggle action enabled/disabled."""
    action = get_action(action_id)
    if not action:
        return jsonify({"error": "Action not found"}), 404

    user = current_user()
    site = get_site(action["site_id"])
    if not site or not _user_owns_site(user, site):
        return jsonify({"error": "Forbidden"}), 403

    new_state = toggle_action(action_id)
    if new_state is None:
        return jsonify({"error": "Action not found"}), 404

    updated = get_action(action_id)
    return jsonify({"action": updated, "enabled": new_state}), 200


def _user_owns_site(user, site):
    """Check if user owns the site (or has team access)."""
    if not user:
        return False
    return user.get("id") == site.get("user_id")


@actions_bp.route("/validate/chain", methods=["POST"])
@login_required
def validate_chain_endpoint():
    """Validate a chain configuration without creating it."""
    from app.services.chain_engine import validate_chain

    data = request.get_json(force=True)
    config = data.get("config", {})

    validation = validate_chain(config)
    return jsonify(validation), 200 if validation["valid"] else 400


@actions_bp.route("/chains/quota", methods=["GET"])
@login_required
def chain_quota():
    """Get current chain usage and limits for the authenticated user."""
    from app.models import check_chain_quota, get_user_chain_count

    user = current_user()
    allowed, current_count, max_chains = check_chain_quota(user["id"])
    tier_config = TIERS.get(user.get("tier", "free"), TIERS["free"])
    return jsonify(
        {
            "allowed": allowed,
            "current_count": current_count,
            "max_chains": max_chains,
            "unlimited": max_chains == -1,
            "available": max_chains - current_count if max_chains > 0 else None,
            "tier": user.get("tier", "free"),
            "tier_name": tier_config["name"],
        }
    ), 200
