"""MOCO API integration for offer creation."""
from datetime import datetime, timedelta
from typing import Optional

import httpx
from loguru import logger

from src.config import settings


def _headers() -> dict:
    return {
        "Authorization": f"Token token={settings.moco_api_key}",
        "Content-Type": "application/json",
    }


def _base_url() -> str:
    return f"https://{settings.moco_domain}.mocoapp.com/api/v1"


async def search_moco_companies(term: str) -> list[dict]:
    """Search MOCO companies by name term.

    Returns a list of dicts with keys: id, name.
    """
    if not settings.moco_api_key or not settings.moco_domain:
        logger.warning("MOCO not configured (moco_api_key / moco_domain missing)")
        return []

    params = {"type": "customer"}
    if term:
        params["term"] = term

    try:
        async with httpx.AsyncClient(timeout=10.0) as client:
            response = await client.get(
                f"{_base_url()}/companies",
                headers=_headers(),
                params=params,
            )
            response.raise_for_status()
            companies = response.json()
            return [{"id": c["id"], "name": c["name"]} for c in companies]
    except httpx.HTTPStatusError as e:
        logger.error(f"MOCO companies search failed ({e.response.status_code}): {e.response.text}")
        raise
    except Exception as e:
        logger.error(f"MOCO companies search error: {e}")
        raise


async def _get_company_details(company_id: int) -> Optional[dict]:
    """Fetch a MOCO company by ID. Returns the company dict or None."""
    try:
        async with httpx.AsyncClient(timeout=10.0) as client:
            response = await client.get(
                f"{_base_url()}/companies/{company_id}",
                headers=_headers(),
            )
            response.raise_for_status()
            return response.json()
    except Exception as e:
        logger.warning(f"Could not fetch MOCO company {company_id}: {e}")
        return None


async def _get_company_contact(company_id: int, company_name: str) -> Optional[dict]:
    """Return the first contact person associated with the given MOCO company.

    MOCO's /contacts/people has no company_id filter, so we search by company
    name and then filter client-side on company.id.
    """
    try:
        async with httpx.AsyncClient(timeout=10.0) as client:
            response = await client.get(
                f"{_base_url()}/contacts/people",
                headers=_headers(),
                params={"term": company_name},
            )
            response.raise_for_status()
            people = response.json()

        # Filter to contacts whose company.id matches exactly
        matched = [
            p for p in people
            if (p.get("company") or {}).get("id") == company_id
        ]
        contact = matched[0] if matched else None
        if contact:
            logger.debug(
                f"MOCO contact for company {company_id}: "
                f"gender={contact.get('gender')!r} lastname={contact.get('lastname')!r}"
            )
        else:
            logger.debug(f"No contact found for MOCO company {company_id} ({company_name!r})")
        return contact
    except Exception as e:
        logger.warning(f"Could not fetch MOCO contacts for company {company_id}: {e}")
        return None


def _build_salutation_html(contact: Optional[dict]) -> str:
    """Build an HTML salutation block from a MOCO contact dict."""
    if not contact:
        greeting = "Sehr geehrte Damen und Herren"
    else:
        gender = (contact.get("gender") or "").strip().upper()
        lastname = (contact.get("lastname") or "").strip()
        logger.debug(f"MOCO contact gender={gender!r} lastname={lastname!r}")

        if gender == "M":
            greeting = f"Sehr geehrter Herr {lastname}".strip()
        elif gender == "F":
            greeting = f"Sehr geehrte Frau {lastname}".strip()
        else:
            greeting = "Sehr geehrte Damen und Herren"

    return (
        f"<p>{greeting},</p>"
        "<p>vielen Dank für Ihre Anfrage. Anbei finden Sie ein ausgearbeitetes Angebot "
        "für die von Ihnen angefragten Leistungen.</p>"
    )


def _build_footer_html() -> str:
    """Build the HTML footer using MOCO's native {customer_approval_link} variable.

    MOCO replaces {customer_approval_link} with a properly formatted and
    clickable link at render/send time. Using a manual <a> tag causes MOCO
    to override the link text with its own '[identifier] Angebot' format.
    """
    return (
        "<p>Wir freuen uns über Ihre Bestätigung per E-Mail oder direkt über diesen Link: "
        "{customer_approval_link}</p>"
        "<p>Freundliche Grüße,<br>"
        "Olivia Kibele<br>"
        "olivia.kibele@onyva.de<br>"
        "0751 18523411</p>"
    )


async def create_moco_offer(
    company_id: int,
    company_name: str,
    price: float,
    payment_frequency: str,
    plan_name: str,
    max_employees: int,
    daily_token_limit: Optional[int],
) -> dict:
    """Create an offer in MOCO and return the full offer object."""
    today = datetime.utcnow().date()
    due_date = today + timedelta(days=30)

    # Fetch company details for billing address + contact lookup
    company = await _get_company_details(company_id)
    recipient_address = (
        (company.get("address") or "").strip() or company_name
        if company else company_name
    )

    contact = await _get_company_contact(company_id, company_name)
    salutation_html = _build_salutation_html(contact)

    if daily_token_limit:
        posts_per_month = int(daily_token_limit * 30 / 50_000)
        token_detail = (
            f"{daily_token_limit:,}".replace(",", ".") +
            f" Tokens/Tag (ca. {posts_per_month} Posts/Monat)"
        )
    else:
        token_detail = "Unbegrenzt"

    freq_label = payment_frequency.capitalize()
    offer_title = f"LinkedIn Content Automation – {plan_name}"

    description_text = (
        f"LinkedIn Content Automation – {plan_name}\n\n"
        f"Lizenzdetails:\n"
        f"• Mitarbeiter: {max_employees} Nutzer\n"
        f"• KI-Token-Limit: {token_detail}\n"
        f"• Zahlungsweise: {freq_label}\n\n"
        f"Enthaltene Funktionen:\n"
        f"• LinkedIn-Profil-Analyse (KI-gestützt)\n"
        f"• Post-Typen & Strategie mit Gewichtung\n"
        f"• KI-Post-Erstellung (chat-basiert, iterativ)\n"
        f"• Mitarbeiterverwaltung & Freigabe-Workflows\n"
        f"• Research-Funktion & Posting-Kalender\n"
        f"• E-Mail-Benachrichtigungen"
    )

    payload = {
        "company_id": company_id,
        "recipient_address": recipient_address,
        "date": today.isoformat(),
        "due_date": due_date.isoformat(),
        "title": offer_title,
        "tax": 19.0,
        "currency": "EUR",
        "discount": 0,
        "salutation": salutation_html,
        "footer": _build_footer_html(),
        "items": [
            {
                "type": "description",
                "title": "Leistungsbeschreibung",
                "description": description_text,
            },
            {
                "type": "item",
                "title": f"Lizenz – {plan_name}",
                "description": f"{max_employees} Nutzer · {token_detail} · {freq_label}",
                "quantity": 1,
                "unit": "Monat" if payment_frequency == "monatlich" else "Pauschal",
                "unit_price": price,
                "net_total": price,
            },
        ],
    }

    try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            response = await client.post(
                f"{_base_url()}/offers",
                headers=_headers(),
                json=payload,
            )
            response.raise_for_status()
            offer = response.json()
            logger.info(
                f"MOCO offer created: id={offer.get('id')}, identifier={offer.get('identifier')}"
            )
            return offer

    except httpx.HTTPStatusError as e:
        logger.error(f"MOCO offer creation failed ({e.response.status_code}): {e.response.text}")
        raise
    except Exception as e:
        logger.error(f"MOCO offer creation error: {e}")
        raise


async def send_moco_offer(moco_offer_id: int) -> None:
    """Send a MOCO offer to its default recipients via email.

    Uses POST /offers/{id}/send_email with empty recipient lists so MOCO
    falls back to the default recipients configured on the customer.
    """
    payload = {
        "subject": "Ihr Angebot – LinkedIn Content Automation",
        "text": (
            "Anbei finden Sie unser Angebot für die LinkedIn Content Automation Plattform.\n\n"
            "Bitte bestätigen Sie direkt über den Link im Angebot.\n\n"
            "Freundliche Grüße,\nOlivia Kibele"
        ),
    }
    try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            response = await client.post(
                f"{_base_url()}/offers/{moco_offer_id}/send_email",
                headers=_headers(),
                json=payload,
            )
            response.raise_for_status()
            logger.info(f"MOCO offer {moco_offer_id} sent via email")
    except httpx.HTTPStatusError as e:
        logger.error(f"MOCO send_email failed ({e.response.status_code}): {e.response.text}")
        raise
    except Exception as e:
        logger.error(f"MOCO send_email error: {e}")
        raise
