"""Customer routes.

Moved from app.admin_dashboard in v4.7.2. The handlers still reuse
legacy helpers to keep this refactor behavior-preserving.
"""
from fastapi import APIRouter
import re
from fastapi.responses import PlainTextResponse
import app.admin_dashboard as legacy
from app.admin_dashboard import *  # noqa: F401,F403

router = APIRouter()

_EMAIL_RE = re.compile(r"^[^\s@]+@[^\s@]+\.[^\s@]+$")

def _valid_optional_email(value: str) -> bool:
    value = str(value or "").strip()
    return not value or bool(_EMAIL_RE.match(value))


@router.get("/customers", response_class=HTMLResponse)
@router.get("/clientes", response_class=HTMLResponse)
async def customers_page(q: Optional[str] = None):
    try:
        from app.commercial_service import list_customers
        customer_rows = list_customers(q=q, limit=300)
        error = ""
    except Exception as exc:
        customer_rows = []
        error = str(exc)

    rows = ""
    for c in customer_rows:
        jasmin_state = "Ligado" if c.get("jasmin_customer_party_key") else "Por validar"
        jasmin_cls = "cf-chip-green" if c.get("jasmin_customer_party_key") else "cf-chip-orange"
        rows += f"""
        <tr>
          <td><a class="cf-row-link" href="/customers/{esc(c.get('id'))}">{esc(c.get('name') or 'Cliente')}</a><div class="small text-secondary">NIF {esc(c.get('tax_id') or '—')}</div></td>
          <td><div class="text-break">{esc(c.get('email') or '—')}</div><div class="small text-secondary">{esc(c.get('phone') or '')}</div></td>
          <td>{esc(c.get('city_name') or '—')}<div class="small text-secondary">{esc(c.get('postal_zone') or '')}</div></td>
          <td><span class="cf-chip {jasmin_cls}">{esc(jasmin_state)}</span><div class="small text-secondary"><code>{esc(c.get('jasmin_customer_party_key') or '')}</code></div></td>
          <td><span class="cf-chip cf-chip-blue">{int(c.get('opportunity_count') or 0)} oportunidades</span></td>
          <td>{esc(fmt_dt(c.get('updated_at')))}</td>
        </tr>
        """
    if not rows:
        rows = '<tr><td colspan="6" class="text-center text-secondary py-5">Sem clientes locais. Cria uma ficha ou associa a partir de uma oportunidade.</td></tr>'

    error_html = f'<div class="alert alert-warning">{esc(error)}</div>' if error else ''
    body = f"""
    <div class="row g-3 mb-3">
      <div class="col-lg-8">
        <section class="card cf-card cf-filter-card">
          <form method="get" action="/customers" class="row g-3 align-items-end">
            <div class="col-lg-8"><label class="form-label small fw-bold text-secondary">Procurar cliente</label><input class="form-control" type="search" name="q" value="{esc(q or '')}" placeholder="nome, NIF, email, telefone..."></div>
            <div class="col-lg-4 d-flex gap-2"><button class="btn btn-primary flex-fill" type="submit">Filtrar</button><a class="btn btn-outline-secondary" href="/customers">Limpar</a></div>
          </form>
        </section>
      </div>
      <div class="col-lg-4">
        <section class="card cf-card"><div class="card-body p-3"><h2 class="cf-section-title mb-2">Novo cliente</h2><form method="post" action="/customers/create" class="d-grid gap-2"><input class="form-control" name="name" placeholder="Nome fiscal" required><input class="form-control" name="tax_id" placeholder="NIF"><button class="btn btn-primary" type="submit">Criar ficha</button></form></div></section>
      </div>
    </div>
    {error_html}
    <section class="card cf-card"><div class="card-body p-0"><div class="p-3 border-bottom"><h2 class="cf-section-title">Clientes</h2><div class="small text-secondary">Dados fiscais e moradas vivem aqui. A oportunidade mostra só o estado da compra.</div></div><div class="cf-table-wrap border-0 rounded-0"><table class="table cf-table"><thead><tr><th>Cliente</th><th>Contactos</th><th>Localidade</th><th>Jasmin</th><th>Pipeline</th><th>Atualizado</th></tr></thead><tbody>{rows}</tbody></table></div></div></section>
    """
    return layout("Clientes", "Ficha fiscal, contactos e documentos por cliente", body, "customers")


@router.post("/customers/create")
async def create_customer_action(request: Request):
    form = await request.form()
    try:
        from app.commercial_service import upsert_customer
        customer = upsert_customer({
            "name": str(form.get("name") or "").strip(),
            "tax_id": str(form.get("tax_id") or "").strip(),
            "email": str(form.get("email") or "").strip(),
            "phone": str(form.get("phone") or "").strip(),
        })
    except ValueError as exc:
        return PlainTextResponse(f"Dados inválidos ao criar cliente: {exc}", status_code=422)
    except Exception as exc:
        return PlainTextResponse(f"Erro ao criar cliente: {exc}", status_code=500)
    return RedirectResponse(f"/customers/{customer.get('id')}", status_code=303)


@router.get("/customers/new", response_class=HTMLResponse)
async def customer_new_page(name: Optional[str] = None, tax_id: Optional[str] = None, email: Optional[str] = None):
    body = f"""
    <a class="cf-row-link d-inline-flex mb-3" href="/customers">← Voltar a clientes</a>
    <section class="card cf-card">
      <div class="card-body p-4">
        <h1 class="h4 fw-bold mb-1">Novo cliente fiscal</h1>
        <div class="text-secondary mb-4">Cria uma ficha fiscal para associar a oportunidades, documentos Jasmin e processos de envio.</div>
        <form method="post" action="/customers/create" class="row g-3">
          <div class="col-12"><label class="form-label small fw-bold text-secondary">Nome fiscal</label><input class="form-control" name="name" value="{esc(name or '')}" placeholder="Nome fiscal" required></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">NIF</label><input class="form-control" name="tax_id" value="{esc(tax_id or '')}" placeholder="NIF"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Email</label><input class="form-control" name="email" value="{esc(email or '')}" placeholder="email@empresa.pt"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Telefone</label><input class="form-control" name="phone" placeholder="Telefone"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">País</label><input class="form-control" name="country" value="PT"></div>
          <div class="col-12 d-flex gap-2"><button class="btn btn-primary" type="submit">Criar ficha</button><a class="btn btn-outline-secondary" href="/customers">Cancelar</a></div>
        </form>
      </div>
    </section>
    """
    return layout("Novo cliente", "Criar ficha fiscal", body, "customers")


@router.get("/customers/{customer_id}", response_class=HTMLResponse)
async def customer_detail_page(customer_id: str):
    if not is_uuid_text(customer_id):
        return PlainTextResponse("Identificador de cliente inválido.", status_code=422)
    try:
        from app.commercial_service import get_customer, list_commercial_documents, list_opportunities_for_customer, list_shipments
        customer = get_customer(customer_id)
        if not customer:
            return layout("Cliente não encontrado", "Clientes", '<section class="cf-empty">Cliente não encontrado.</section>', "customers")
        docs = list_commercial_documents(customer_id=customer_id, limit=100)
        opps = list_opportunities_for_customer(customer_id, limit=50)
        shipments = list_shipments(customer_id=customer_id, limit=50)
    except Exception as exc:
        return PlainTextResponse(f"Erro ao abrir cliente: {exc}", status_code=500)

    doc_rows = ""
    for d in docs:
        number = d.get("document_number") or " ".join([str(d.get("document_type") or ""), str(d.get("serie") or ""), str(d.get("series_number") or "")]).strip() or d.get("external_id") or "—"
        kind = {"quotation": "Orçamento", "invoice": "Fatura"}.get(str(d.get("document_kind") or ""), d.get("document_kind") or "Documento")
        doc_rows += f"<tr><td>{esc(kind)}</td><td><code>{esc(number)}</code></td><td>{operation_status_badge(str(d.get('status') or 'created'))}</td><td>{money_html(d.get('total_amount') or d.get('amount') or 0)}</td><td>{esc(fmt_dt(d.get('created_at')))}</td></tr>"
    if not doc_rows:
        doc_rows = '<tr><td colspan="5" class="text-secondary py-4">Sem documentos Jasmin locais.</td></tr>'

    opp_rows = ""
    for o in opps:
        opp_rows += f"<tr><td><a class='cf-row-link' href='/opportunities/{esc(o.get('id'))}'>{esc(o.get('title') or 'Oportunidade')}</a><div class='small text-secondary'>{esc(o.get('product_interest') or '')}</div></td><td>{opportunity_stage_badge(o.get('stage'))}</td><td>{money_html(o.get('value_amount') or 0)}</td><td>{esc(fmt_dt(o.get('updated_at')))}</td></tr>"
    if not opp_rows:
        opp_rows = '<tr><td colspan="4" class="text-secondary py-4">Sem oportunidades associadas.</td></tr>'

    shipment_rows = ""
    for sh in shipments:
        shipment_rows += f"<tr><td>{esc(sh.get('carrier') or '—')}</td><td>{esc(sh.get('service_name') or '—')}</td><td>{operation_status_badge(str(sh.get('status') or 'created'))}</td><td><code>{esc(sh.get('external_reference') or '')}</code></td><td>{esc(sh.get('tracking_code') or '—')}</td></tr>"
    if not shipment_rows:
        shipment_rows = '<tr><td colspan="5" class="text-secondary py-4">Sem envios Packlink locais.</td></tr>'

    body = f"""
    <a class="cf-row-link d-inline-flex mb-3" href="/customers">← Voltar a clientes</a>
    <div class="row g-3">
      <div class="col-lg-5">
        <section class="card cf-card"><div class="card-body p-4"><h1 class="h4 fw-bold mb-1">{esc(customer.get('name'))}</h1><div class="text-secondary mb-3">NIF {esc(customer.get('tax_id') or '—')}</div><form method="post" action="/customers/{esc(customer_id)}/update" class="row g-3">
          <div class="col-12"><label class="form-label small fw-bold text-secondary">Nome fiscal</label><input class="form-control" name="name" value="{esc(customer.get('name') or '')}" required></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">NIF</label><input class="form-control" name="tax_id" value="{esc(customer.get('tax_id') or '')}"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">País</label><input class="form-control" name="country" value="{esc(customer.get('country') or 'PT')}"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Email</label><input class="form-control" name="email" value="{esc(customer.get('email') or '')}"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Telefone</label><input class="form-control" name="phone" value="{esc(customer.get('phone') or '')}"></div>
          <div class="col-12"><label class="form-label small fw-bold text-secondary">Morada fiscal</label><input class="form-control" name="street_name" value="{esc(customer.get('street_name') or '')}"></div>
          <div class="col-md-5"><label class="form-label small fw-bold text-secondary">Código postal</label><input class="form-control" name="postal_zone" value="{esc(customer.get('postal_zone') or '')}"></div>
          <div class="col-md-7"><label class="form-label small fw-bold text-secondary">Cidade</label><input class="form-control" name="city_name" value="{esc(customer.get('city_name') or '')}"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Jasmin partyKey</label><input class="form-control" name="jasmin_customer_party_key" value="{esc(customer.get('jasmin_customer_party_key') or '')}"></div>
          <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Jasmin ID</label><input class="form-control" name="jasmin_customer_id" value="{esc(customer.get('jasmin_customer_id') or '')}"></div>
          <div class="col-12"><button class="btn btn-primary" type="submit">Guardar cliente</button></div>
        </form></div></section>
      </div>
      <div class="col-lg-7 d-grid gap-3">
        <section class="card cf-card"><div class="card-body p-3">
          <div class="d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3"><div><h2 class="cf-section-title mb-1">Nova oportunidade</h2><div class="small text-secondary">Cria um processo comercial manual já ligado a este cliente fiscal.</div></div></div>
          <form method="post" action="/customers/{esc(customer_id)}/opportunities/create" class="row g-2 align-items-end">
            <div class="col-md-3"><label class="form-label small fw-bold text-secondary">Origem</label><select class="form-select" name="origin"><option value="phone">Telefone</option><option value="whatsapp">WhatsApp</option><option value="email">Email</option><option value="presential">Presencial</option><option value="manual">Manual</option></select></div>
            <div class="col-md-3"><label class="form-label small fw-bold text-secondary">Pedido</label><select class="form-select" name="request_type"><option value="quote">Orçamento</option><option value="info">Informação</option><option value="invoice">Fatura</option><option value="order">Encomenda</option><option value="support">Assistência</option></select></div>
            <div class="col-md-6"><label class="form-label small fw-bold text-secondary">Produto/interesse</label><input class="form-control" name="product_interest" placeholder="Ex.: carregador monofásico, cabo, instalação..."></div>
            <div class="col-md-4"><label class="form-label small fw-bold text-secondary">Contacto</label><input class="form-control" name="contact_name" placeholder="Nome do contacto"></div>
            <div class="col-md-4"><label class="form-label small fw-bold text-secondary">Email contacto</label><input class="form-control" name="contact_email" placeholder="email@empresa.pt"></div>
            <div class="col-md-4"><label class="form-label small fw-bold text-secondary">Telefone contacto</label><input class="form-control" name="contact_phone" placeholder="telefone"></div>
            <div class="col-12"><label class="form-label small fw-bold text-secondary">Notas</label><textarea class="form-control" name="notes" rows="2" placeholder="Resumo do pedido, contexto da chamada ou próximos passos"></textarea></div>
            <div class="col-md-8"><div class="form-check"><input class="form-check-input" type="checkbox" name="create_task" value="1" id="create-task-from-customer" checked><label class="form-check-label small" for="create-task-from-customer">Criar tarefa inicial para a próxima ação</label></div></div>
            <div class="col-md-4 d-grid"><button class="btn btn-primary" type="submit">Criar oportunidade</button></div>
          </form>
        </div></section>
        <section class="card cf-card"><div class="card-body p-0"><div class="p-3 border-bottom"><h2 class="cf-section-title">Oportunidades</h2></div><div class="cf-table-wrap border-0 rounded-0"><table class="table cf-table"><thead><tr><th>Oportunidade</th><th>Estado</th><th>Valor</th><th>Atualizada</th></tr></thead><tbody>{opp_rows}</tbody></table></div></div></section>
        <section class="card cf-card"><div class="card-body p-0"><div class="p-3 border-bottom"><h2 class="cf-section-title">Documentos Jasmin</h2></div><div class="cf-table-wrap border-0 rounded-0"><table class="table cf-table"><thead><tr><th>Tipo</th><th>Número/ID</th><th>Estado</th><th>Valor</th><th>Criado</th></tr></thead><tbody>{doc_rows}</tbody></table></div></div></section>
        <section class="card cf-card"><div class="card-body p-0"><div class="p-3 border-bottom"><h2 class="cf-section-title">Envios Packlink</h2></div><div class="cf-table-wrap border-0 rounded-0"><table class="table cf-table"><thead><tr><th>Transportadora</th><th>Serviço</th><th>Estado</th><th>Referência</th><th>Tracking</th></tr></thead><tbody>{shipment_rows}</tbody></table></div></div></section>
      </div>
    </div>
    """
    return layout(str(customer.get("name") or "Cliente"), "Ficha fiscal, oportunidades e documentos", body, "customers")


@router.post("/customers/{customer_id}/opportunities/create")
async def create_customer_opportunity_action(customer_id: str, request: Request):
    if not is_uuid_text(customer_id):
        return PlainTextResponse("Identificador de cliente inválido.", status_code=422)
    form = await request.form()
    contact_email = str(form.get("contact_email") or "").strip()
    if not _valid_optional_email(contact_email):
        return PlainTextResponse("Email de contacto inválido.", status_code=422)
    meaningful = any(str(form.get(k) or "").strip() for k in ("contact_name", "contact_phone", "product_interest", "notes")) or bool(contact_email)
    if not meaningful:
        return PlainTextResponse("Dados insuficientes para criar oportunidade.", status_code=422)
    if contact_email and not any(str(form.get(k) or "").strip() for k in ("contact_name", "contact_phone", "product_interest", "notes")):
        return PlainTextResponse("Dados insuficientes para criar oportunidade: indique produto, notas ou outro contacto válido.", status_code=422)
    try:
        from app.opportunity_service import create_manual_opportunity_from_customer
        result = create_manual_opportunity_from_customer(
            customer_id,
            origin=str(form.get("origin") or "phone").strip(),
            request_type=str(form.get("request_type") or "quote").strip(),
            contact_name=str(form.get("contact_name") or "").strip(),
            contact_email=str(form.get("contact_email") or "").strip(),
            contact_phone=str(form.get("contact_phone") or "").strip(),
            product_interest=str(form.get("product_interest") or "").strip(),
            notes=str(form.get("notes") or "").strip(),
            create_task=bool(form.get("create_task")),
            created_by="operator",
        )
    except ValueError as exc:
        return PlainTextResponse(f"Dados inválidos ao criar oportunidade: {exc}", status_code=422)
    except Exception as exc:
        return PlainTextResponse(f"Erro ao criar oportunidade: {exc}", status_code=500)
    return RedirectResponse(result.get("next_url") or f"/customers/{customer_id}", status_code=303)


@router.post("/customers/{customer_id}/update")
async def update_customer_action(customer_id: str, request: Request):
    if not is_uuid_text(customer_id):
        return PlainTextResponse("Identificador de cliente inválido.", status_code=422)
    form = await request.form()
    try:
        from app.commercial_service import update_customer
        update_customer(customer_id, {
            "name": str(form.get("name") or "").strip(),
            "tax_id": str(form.get("tax_id") or "").strip(),
            "email": str(form.get("email") or "").strip(),
            "phone": str(form.get("phone") or "").strip(),
            "street_name": str(form.get("street_name") or "").strip(),
            "postal_zone": str(form.get("postal_zone") or "").strip(),
            "city_name": str(form.get("city_name") or "").strip(),
            "country": str(form.get("country") or "PT").strip(),
            "jasmin_customer_party_key": str(form.get("jasmin_customer_party_key") or "").strip(),
            "jasmin_customer_id": str(form.get("jasmin_customer_id") or "").strip(),
        })
    except ValueError as exc:
        return PlainTextResponse(f"Dados inválidos ao guardar cliente: {exc}", status_code=422)
    except Exception as exc:
        # Keep database details out of the operator UI. Duplicate NIFs are a
        # business conflict, not a technical 500.
        status = 409 if exc.__class__.__name__ == "DuplicateCustomerTaxIdError" else 500
        return PlainTextResponse(f"Erro ao guardar cliente: {exc}", status_code=status)
    return RedirectResponse(f"/customers/{customer_id}", status_code=303)


