"""Retail intelligence map page + API proxy."""
from __future__ import annotations

import os
from typing import Any, Optional

import httpx
from fastapi import APIRouter, Query, Request
from fastapi.responses import JSONResponse, StreamingResponse
from fastapi.templating import Jinja2Templates
from pathlib import Path
from pydantic import BaseModel

router = APIRouter()
BASE = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=str(BASE / "templates"))
TOOLS = os.getenv("TOOLS_API_URL", "http://tools-api:8700").rstrip("/")


class CrmLinkBody(BaseModel):
    client_id: int
    deal_id: Optional[int] = None
    relationship_type: str = "prospect"
    partnership_status: Optional[str] = None
    notes: Optional[str] = None


class SupermarketCreateBody(BaseModel):
    name: str
    chain: str
    address: str
    postcode: str = "0000AA"
    city: str
    province: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    website: Optional[str] = None
    manager_name: Optional[str] = None
    employee_count: Optional[int] = None
    store_type: Optional[str] = None
    partnership_status: str = "none"
    halal_certified: bool = False
    has_halal_section: bool = False
    halal_certifier: Optional[str] = None


class SupermarketPatchBody(BaseModel):
    name: Optional[str] = None
    chain: Optional[str] = None
    address: Optional[str] = None
    postcode: Optional[str] = None
    city: Optional[str] = None
    province: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    website: Optional[str] = None
    manager_name: Optional[str] = None
    employee_count: Optional[int] = None
    store_type: Optional[str] = None
    size_m2: Optional[int] = None
    partnership_status: Optional[str] = None
    halal_certified: Optional[bool] = None
    has_halal_section: Optional[bool] = None
    halal_certifier: Optional[str] = None
    halal_certificate_number: Optional[str] = None
    organic_section: Optional[bool] = None
    alcohol_section: Optional[bool] = None


class NoteBody(BaseModel):
    body: str
    title: Optional[str] = None
    note_type: str = "general"


class MilestoneBody(BaseModel):
    title: str
    milestone_type: str = "custom"
    client_id: Optional[int] = None
    deal_id: Optional[int] = None
    target_date: Optional[str] = None
    value_eur: Optional[float] = None
    notes: Optional[str] = None


class OwnershipBody(BaseModel):
    new_owner: str
    previous_owner: Optional[str] = None
    change_type: str = "acquisition"
    effective_date: Optional[str] = None
    source: Optional[str] = None
    notes: Optional[str] = None


class CalendarBody(BaseModel):
    title: str
    starts_at: str
    description: Optional[str] = None
    ends_at: Optional[str] = None
    client_id: Optional[int] = None
    deal_id: Optional[int] = None
    location: Optional[str] = None


class MediaBody(BaseModel):
    filename: str
    storage_path: str
    content_type: str = "image/jpeg"
    caption: Optional[str] = None


async def _tools_get(path: str, params: Optional[dict] = None) -> Any:
    async with httpx.AsyncClient(timeout=120) as client:
        resp = await client.get(f"{TOOLS}{path}", params=params or {})
        resp.raise_for_status()
        return resp.json()


async def _tools_post(path: str, params: Optional[dict] = None, json_body: Optional[dict] = None) -> Any:
    async with httpx.AsyncClient(timeout=300) as client:
        resp = await client.post(f"{TOOLS}{path}", params=params or {}, json=json_body)
        resp.raise_for_status()
        return resp.json()


async def _tools_delete(path: str) -> Any:
    async with httpx.AsyncClient(timeout=60) as client:
        resp = await client.delete(f"{TOOLS}{path}")
        resp.raise_for_status()
        return resp.json()


async def _tools_patch(path: str, json_body: Optional[dict] = None) -> Any:
    async with httpx.AsyncClient(timeout=120) as client:
        resp = await client.patch(f"{TOOLS}{path}", json=json_body or {})
        resp.raise_for_status()
        return resp.json()


@router.get("/retail")
async def retail_page(request: Request):
    stats = await _tools_get("/retail/stats")
    filters = await _tools_get("/retail/filters")
    schema = await _tools_get("/retail/schema")
    trends = await _tools_get("/retail/trends", {"limit": 8})
    crm = await _tools_get("/retail/crm/options")
    return templates.TemplateResponse(
        "retail.html",
        {
            "request": request,
            "stats": stats,
            "filters": filters,
            "schema": schema,
            "trends": trends.get("items", []),
            "crm_options": crm,
        },
    )


@router.get("/api/retail/stats")
async def api_retail_stats(request: Request):
    return JSONResponse(await _tools_get("/retail/stats", dict(request.query_params)))


@router.get("/api/retail/filters")
async def api_retail_filters():
    return JSONResponse(await _tools_get("/retail/filters"))


@router.get("/api/retail/map")
async def api_retail_map(request: Request):
    return JSONResponse(await _tools_get("/retail/map", dict(request.query_params)))


@router.get("/api/retail/list")
async def api_retail_list(request: Request):
    return JSONResponse(await _tools_get("/retail/supermarkets", dict(request.query_params)))


@router.get("/api/retail/supermarkets/{store_id}")
async def api_retail_store(store_id: int):
    return JSONResponse(await _tools_get(f"/retail/supermarkets/{store_id}"))


@router.get("/api/retail/opportunities")
async def api_retail_opportunities(request: Request):
    return JSONResponse(await _tools_get("/retail/opportunities", dict(request.query_params)))


@router.get("/api/retail/trends")
async def api_retail_trends(request: Request):
    return JSONResponse(await _tools_get("/retail/trends", dict(request.query_params)))


@router.get("/api/retail/crm/options")
async def api_crm_options():
    return JSONResponse(await _tools_get("/retail/crm/options"))


@router.post("/api/retail/supermarkets/{store_id}/link")
async def api_link_store(store_id: int, body: CrmLinkBody):
    return JSONResponse(await _tools_post(f"/retail/supermarkets/{store_id}/link", json_body=body.model_dump()))


@router.post("/api/retail/supermarkets")
async def api_create_supermarket(body: SupermarketCreateBody):
    return JSONResponse(await _tools_post("/retail/supermarkets", json_body=body.model_dump()))


@router.patch("/api/retail/supermarkets/{store_id}")
async def api_patch_supermarket(store_id: int, body: SupermarketPatchBody):
    return JSONResponse(await _tools_patch(
        f"/retail/supermarkets/{store_id}",
        json_body=body.model_dump(exclude_unset=True),
    ))


@router.delete("/api/retail/supermarkets/{store_id}/link/{client_id}")
async def api_unlink_store(store_id: int, client_id: int):
    return JSONResponse(await _tools_delete(f"/retail/supermarkets/{store_id}/link/{client_id}"))


@router.post("/api/retail/enrich")
async def api_retail_enrich(limit: int = Query(100, ge=1, le=200)):
    return JSONResponse(await _tools_post("/retail/enrich", params={"limit": limit}))


@router.post("/api/retail/sync/{action}")
async def api_retail_sync(action: str, limit: int = Query(100, ge=1, le=300)):
    paths = {
        "halal": "/retail/sync/halal",
        "contacts": f"/retail/sync/contacts?limit={limit}",
        "trends": "/retail/sync/trends",
        "opportunities": "/retail/compute-opportunities",
    }
    if action not in paths:
        return JSONResponse({"error": "unknown action"}, status_code=400)
    return JSONResponse(await _tools_post(paths[action]))


@router.get("/api/retail/export")
async def api_retail_export(request: Request):
    async with httpx.AsyncClient(timeout=120) as client:
        resp = await client.get(f"{TOOLS}/retail/export", params=dict(request.query_params))
        resp.raise_for_status()
        return StreamingResponse(
            iter([resp.text]),
            media_type="text/csv",
            headers={"Content-Disposition": "attachment; filename=retail_export.csv"},
        )


# --- 360 workspace proxies ---

@router.get("/api/retail/360/{store_id}")
async def api_retail_360(store_id: int):
    return JSONResponse(await _tools_get(f"/retail/360/{store_id}"))


@router.post("/api/retail/360/{store_id}/notes")
async def api_retail_note(store_id: int, body: NoteBody):
    return JSONResponse(await _tools_post(f"/retail/360/{store_id}/notes", json_body=body.model_dump()))


@router.post("/api/retail/360/{store_id}/milestones")
async def api_retail_milestone(store_id: int, body: MilestoneBody):
    return JSONResponse(await _tools_post(f"/retail/360/{store_id}/milestones", json_body=body.model_dump()))


@router.post("/api/retail/360/{store_id}/ownership")
async def api_retail_ownership(store_id: int, body: OwnershipBody):
    return JSONResponse(await _tools_post(f"/retail/360/{store_id}/ownership", json_body=body.model_dump()))


@router.post("/api/retail/360/{store_id}/calendar")
async def api_retail_calendar(store_id: int, body: CalendarBody):
    return JSONResponse(await _tools_post(f"/retail/360/{store_id}/calendar", json_body=body.model_dump()))


@router.post("/api/retail/360/{store_id}/media")
async def api_retail_media(store_id: int, body: MediaBody):
    return JSONResponse(await _tools_post(f"/retail/360/{store_id}/media", json_body=body.model_dump()))


@router.get("/api/retail/cities")
async def api_retail_cities(request: Request):
    return JSONResponse(await _tools_get("/retail/cities", dict(request.query_params)))


@router.post("/api/retail/cities/sync")
async def api_retail_cities_sync(limit: int = Query(50, ge=1, le=200)):
    return JSONResponse(await _tools_post("/retail/cities/sync", params={"limit": limit}))


@router.get("/api/retail/wholesalers")
async def api_retail_wholesalers(request: Request):
    return JSONResponse(await _tools_get("/retail/wholesalers", dict(request.query_params)))


@router.post("/api/retail/wholesalers/import")
async def api_retail_wholesalers_import():
    return JSONResponse(await _tools_post("/retail/wholesalers/import"))


@router.get("/api/retail/rss/live")
async def api_retail_rss(request: Request):
    return JSONResponse(await _tools_get("/retail/rss/live", dict(request.query_params)))


@router.post("/api/retail/rss/refresh")
async def api_retail_rss_refresh():
    return JSONResponse(await _tools_post("/retail/rss/refresh"))


@router.get("/api/retail/rss/bookmarks")
async def api_rss_bookmarks(request: Request):
    return JSONResponse(await _tools_get("/retail/rss/bookmarks", dict(request.query_params)))


@router.post("/api/retail/rss/bookmarks")
async def api_rss_bookmark_add(request: Request):
    body = await request.json()
    return JSONResponse(await _tools_post("/retail/rss/bookmarks", json_body=body))


@router.delete("/api/retail/rss/bookmarks/{rss_item_id}")
async def api_rss_bookmark_delete(rss_item_id: int):
    return JSONResponse(await _tools_delete(f"/retail/rss/bookmarks/{rss_item_id}"))


@router.get("/api/retail/wholesalers/meta")
async def api_wholesalers_meta():
    return JSONResponse(await _tools_get("/retail/wholesalers/meta"))


@router.get("/api/retail/wholesalers/{wh_id}/contacts")
async def api_wholesaler_contacts(wh_id: int):
    return JSONResponse(await _tools_get(f"/retail/wholesalers/{wh_id}/contacts"))


@router.post("/api/retail/wholesalers/{wh_id}/contacts")
async def api_wholesaler_contact_add(wh_id: int, request: Request):
    body = await request.json()
    return JSONResponse(await _tools_post(f"/retail/wholesalers/{wh_id}/contacts", json_body=body))


@router.get("/api/retail/promo-campaigns")
async def api_promo_campaigns(request: Request):
    return JSONResponse(await _tools_get("/retail/promo-campaigns", dict(request.query_params)))


@router.post("/api/retail/promo-campaigns")
async def api_promo_campaign_add(request: Request):
    body = await request.json()
    return JSONResponse(await _tools_post("/retail/promo-campaigns", json_body=body))


@router.post("/api/retail/reclamefolder/refresh")
async def api_reclamefolder_refresh():
    return JSONResponse(await _tools_post("/retail/reclamefolder/refresh", json_body={}))


@router.get("/api/retail/reclamefolder/live")
async def api_reclamefolder_live(request: Request):
    return JSONResponse(await _tools_get("/retail/reclamefolder/live", dict(request.query_params)))


@router.get("/api/retail/reclamefolder/chains")
async def api_reclamefolder_chains():
    return JSONResponse(await _tools_get("/retail/reclamefolder/chains"))


@router.get("/api/retail/market/supermarkets")
async def api_supermarket_market():
    return JSONResponse(await _tools_get("/retail/market/supermarkets"))


@router.get("/api/retail/market/food-trends")
async def api_food_trends():
    return JSONResponse(await _tools_get("/retail/market/food-trends"))


@router.get("/api/retail/market/concepts")
async def api_market_concepts(request: Request):
    return JSONResponse(await _tools_get("/retail/market/concepts", dict(request.query_params)))


@router.get("/api/retail/live-dashboard")
async def api_retail_live_dashboard():
    return JSONResponse(await _tools_get("/retail/live-dashboard"))


@router.get("/api/retail/market/stocks")
async def api_retail_market_stocks():
    return JSONResponse(await _tools_get("/retail/market/stocks"))


@router.get("/api/retail/regulations")
async def api_retail_regulations(request: Request):
    return JSONResponse(await _tools_get("/retail/regulations", dict(request.query_params)))
