import hashlib

from fastapi import APIRouter, BackgroundTasks, Request

from app.config import settings
from app.db import call_proc
from app.dependencies import limiter
from app.schemas.submissions import (
    ContactFormPayload,
    SmsConsentPayload,
    SubmissionCreated,
)
from app.services.notify import send_contact_notification, send_sms_consent_notification

router = APIRouter(prefix="/api", tags=["submissions"])


def hash_ip(request: Request) -> str | None:
    # Nginx sets X-Forwarded-For; fall back to the socket peer.
    fwd = request.headers.get("x-forwarded-for", "")
    ip = fwd.split(",")[0].strip() or (request.client.host if request.client else "")
    if not ip:
        return None
    return hashlib.sha256(f"{settings.ip_hash_salt}{ip}".encode()).hexdigest()


@router.post("/contact-submissions", response_model=SubmissionCreated, status_code=201)
@limiter.limit("5/hour")
def create_contact_submission(
    payload: ContactFormPayload,
    request: Request,
    background: BackgroundTasks,
) -> dict:
    (new_uuid,) = call_proc(
        "sp_contact_submission_create",
        [
            payload.firstName,
            payload.lastName,
            payload.email,
            payload.phone,
            payload.message,
            None,  # attachment_path
            request.headers.get("referer"),
            hash_ip(request),
            request.headers.get("user-agent", "")[:500],
        ],
        out_count=1,
    )

    # Email the team, but don't make the user wait on SMTP — and don't fail
    # their submission if the mail server is down. The row is already saved.
    background.add_task(send_contact_notification, payload, new_uuid)

    return {"success": True, "id": new_uuid}


@router.post("/sms-consents", response_model=SubmissionCreated, status_code=201)
@limiter.limit("5/hour")
def create_sms_consent(
    payload: SmsConsentPayload,
    request: Request,
    background: BackgroundTasks,
) -> dict:
    consent_text = (
        "By checking this box, I agree to receive SMS text messages from "
        "LarCare Services. Message and data rates may apply."
    )
    (new_uuid,) = call_proc(
        "sp_sms_consent_create",
        [
            payload.firstName,
            payload.lastName,
            payload.email,
            payload.phone,
            1 if payload.consent else 0,
            consent_text,
            hash_ip(request),
        ],
        out_count=1,
    )

    background.add_task(send_sms_consent_notification, payload, new_uuid)

    return {"success": True, "id": new_uuid}


@router.post("/sms-consents/revoke", status_code=204)
def revoke_sms_consent(phone: str) -> None:
    call_proc("sp_sms_consent_revoke", [phone, "webhook"])
