import json
from flask import request, current_app, render_template
from flask_jwt_extended import jwt_required, get_jwt_identity

from app.api import api_bp
from app.utils.auth import role_required
from app.utils.response import ok, fail
from app.services.settings_service import load_settings, update_settings, email_branding_context


ALLOWED_EMAIL_TEMPLATES = [
    "emails/registration_pending.html",
    "emails/password_reset.html",
    "emails/account_status_changed.html",
    "emails/credit_posted.html",
    "emails/loan_request_submitted.html",
    "emails/loan_request_approved.html",
    "emails/loan_request_rejected.html",
    "emails/loan_closed.html",
    "emails/charity_submitted.html",
    "emails/charity_status_changed.html",
    "emails/charity_fund_released.html",
    "emails/release_request_submitted.html",
    "emails/release_request_rejected.html",
    "emails/request_released.html",
]


def _public_company(settings: dict) -> dict:
    company = (settings or {}).get("company", {}) or {}
    return {
        "app_name": company.get("app_name") or "Jana ERP",
        "company_name": company.get("company_name") or company.get("app_name") or "Jana ERP",
        "logo_url": company.get("logo_url") or "",
        "primary_color": company.get("primary_color") or "#1f2937",
        "support_email": company.get("support_email") or "",
    }


@api_bp.get("/settings/public")
def get_public_settings():
    settings = load_settings()
    return ok({"company": _public_company(settings)})


@api_bp.get("/admin/settings")
@role_required("administrator")
def get_admin_settings():
    return ok(load_settings())


@api_bp.get("/access/me")
@jwt_required()
def access_me():
    from app.models.user import User
    from app.services.settings_service import permissions_for_role

    user = User.query.get(get_jwt_identity())
    if not user:
        return fail("Unauthorized", 401)
    return ok({"role": user.access_level, "permissions": permissions_for_role(user.access_level)})


@api_bp.put("/admin/settings")
@role_required("administrator")
def put_admin_settings():
    data = request.json or {}
    try:
        saved = update_settings(data)
        return ok(saved, "Settings saved")
    except Exception as exc:
        current_app.logger.warning("Settings save failed: %s", exc)
        return fail("Failed to save settings", 500)


@api_bp.get("/admin/email-templates")
@role_required("administrator")
def list_email_templates():
    return ok({"templates": ALLOWED_EMAIL_TEMPLATES})


@api_bp.post("/admin/email-preview")
@role_required("administrator")
def preview_email_template():
    data = request.json or {}
    template = data.get("template")
    subject = data.get("subject", "Preview")
    context = data.get("context") or {}
    if template not in ALLOWED_EMAIL_TEMPLATES:
        return fail("Invalid template", 400)

    if isinstance(context, str):
        try:
            context = json.loads(context)
        except Exception:
            return fail("Invalid context JSON", 400)
    if not isinstance(context, dict):
        return fail("Context must be an object", 400)

    html = render_template(template, subject=subject, brand=email_branding_context(), **context)
    return ok({"subject": subject, "template": template, "html": html})
