# Business Analytics Page - Queries and Logic

## Location
- View: `resources/views/filament/pages/business-analytics.blade.php`
- Page class: `app/Filament/Pages/AnalyticsAndAdmin/BusinessAnalytics.php`

## High-Level Flow
- The page is tab-driven (Dashboards, Segments; other tabs exist but are disabled).
- A hidden config element stores active filter state and app scoping for all API calls.
- API requests use a bearer token fetched from `/admin/api/tokens/current` and cached in sessionStorage.

## Shared State
- Config element: `#business-analytics-data-config`
  - `data-date-range-start`
  - `data-date-range-end`
  - `data-segment-filter`
  - `data-app-id` (encrypted app id)
  - `data-last-updated` (mutation observer triggers refresh)

## Authentication / Token Handling
- `getBearerToken()` reads from meta tag, `window.API_BEARER_TOKEN`, or sessionStorage.
- On 401, `refreshBearerToken()` clears storage and retries once.
- Token endpoint: `GET /admin/api/tokens/current`

## Business Analytics Queries (Full Logic)
### Dashboards - Cards + Charts
**Endpoint**
- `GET /admin/business-analytics/widgets/all-data`

**Query params**
- `date_range_start` (YYYY-MM-DD, from config)
- `date_range_end` (YYYY-MM-DD, from config)
- `segment_filter` (from config)
- `app_id` (encrypted app id from config)

**Auth**
- `Authorization: Bearer {token}` from `/admin/api/tokens/current`

**Response shape (used by UI)**
```
{
  "success": true,
  "data": {
    "kpi": {
      "total_revenue": { "value": 0, "change": 0, "trend": "up|down" },
      "mrr": { "value": 0, "change": 0, "trend": "up|down" },
      "arr": { "value": 0, "change": 0, "trend": "up|down" },
      "churn": { "value": 0, "change": 0, "trend": "up|down" },
      "ltv": { "value": 0, "change": 0, "trend": "up|down" },
      "product_activations": { "value": 0, "change": 0, "trend": "up|down" }
    },
    "charts": {
      "mrr_arr_trends": { "labels": [], "datasets": [] },
      "churn_recovery": { "labels": [], "datasets": [] },
      "customer_segments": { "labels": [], "datasets": [] },
      "dunning_success": { "labels": [], "datasets": [] }
    }
  }
}
```

**KPI card mapping**
- `total_revenue` -> `#kpi-total-revenue-value`, `#kpi-total-revenue-trend`
- `mrr` -> `#kpi-mrr-value`, `#kpi-mrr-trend`
- `arr` -> `#kpi-arr-value`, `#kpi-arr-trend`
- `churn` -> `#kpi-churn-value`, `#kpi-churn-trend`
- `ltv` -> `#kpi-ltv-value`, `#kpi-ltv-trend`
- `product_activations` -> `#kpi-recovery-value`, `#kpi-recovery-trend`

**Chart mapping**
- `charts.mrr_arr_trends` -> `#mrr-arr-chart`
  - Accepts `datasets` format; falls back to `{ mrr: [], arr: [] }` if present.
- `charts.churn_recovery` -> `#churn-recovery-chart`
- `charts.customer_segments` -> `#segments-chart` (pie)
- `charts.dunning_success` exists in data but chart rendering is commented out.

**Filter logic**
- Date range dropdown uses `calculateDateRange()` for presets.
- Custom range uses `#ba-date-range-start` and `#ba-date-range-end`.
- Search/Reset buttons update config attributes and trigger fetch.
- `data-last-updated` mutation re-fetches data.

### Segments - Cards + KPIs
**Endpoint**
- `GET /admin/business-analytics/widgets/segments`

**Query params**
- `search` (segments search input)
- `filter` (segment pill filter: `all`, etc.)
- `include_kpis=true`
- `app_id` (encrypted app id)
- `_=timestamp` (only when force reload)

**Auth**
- `Authorization: Bearer {token}`

**Response shape (used by UI)**
```
{
  "success": true,
  "data": {
    "segments": [
      {
        "id": 0,
        "name": "",
        "description": "",
        "type": "",
        "risk": "",
        "subscribers": 0,
        "in_cohort": false,
        "updated_at": ""
      }
    ],
    "kpis": {
      "total_segments": 0,
      "active_segments": 0,
      "users_in_segments": 0,
      "at_risk_users": 0
    }
  }
}
```

**Segments KPI mapping**
- `total_segments` -> `#kpi-total-segments`
- `active_segments` -> `#kpi-active-segments`
- `users_in_segments` -> `#kpi-users-segments`
- `at_risk_users` -> `#kpi-at-risk`
- Derived values:
  - `#kpi-total-categories` = count of unique `segment.type` values.
  - `#kpi-coverage` = `active_segments / total_segments` percent.

**Segments card mapping**
- `segment.name`, `segment.description`, `segment.subscribers`, `segment.updated_at`
- `segment.risk`, `segment.type`, `segment.in_cohort` used for badges/actions.

### Segment Detail - Table + Metrics
**Endpoint**
- `GET /admin/business-analytics/widgets/segments/{segmentId}`

**Query params**
- `page` (default 1)
- `per_page` (default 10)
- `app_id` (encrypted app id)

**Auth**
- `Authorization: Bearer {token}`

**Response shape (used by UI)**
```
{
  "success": true,
  "data": {
    "segment": {
      "id": 0,
      "name": "",
      "description": "",
      "type": "",
      "subscribers": 0,
      "estimated_size": 0,
      "created_by": ""
    },
    "customers": [
      {
        "id": "",
        "subscriber_id": "",
        "email": "",
        "plan": "",
        "price": "",
        "status": ""
      }
    ],
    "pagination": { "current_page": 1, "total": 0 },
    "kpis": { "total_subscribers": 0, "avg_ltv": 0 },
    "churn_metrics": { "at_risk_percent": 0, "stable_percent": 100, "churn_rate": 0 },
    "growth_metrics": { "avg_ltv": 0 }
  }
}
```

**Detail mapping**
- Header: `segment.name`, `segment.description`
- Summary: `segment.type`, `segment.created_by`
- Subscribers count uses (in order): `pagination.total`, `kpis.total_subscribers`, `segment.estimated_size`, `segment.subscribers`
- Churn metrics: `churn_metrics.at_risk_percent` and `stable_percent`
- LTV: `kpis.avg_ltv` or `growth_metrics.avg_ltv`

**Customer table columns**
- `id` / `subscriber_id`, `email`, `plan`, `price`, `status`
- Status badge color determined by status string (active, trial, inactive/cancelled, expired, paused).

### Segment Actions
**Toggle Cohort**
- `POST /admin/analytics-admin/segment/{segmentId}/toggle-cohort`
- Uses `Authorization: Bearer {token}` + CSRF token header.
- Updates segment card state and menu text.

**Export CSV**
- `GET /admin/analytics-admin/segment/{segmentId}/export/csv`
- Triggered from segment detail export menu.

### Segment Builder
**Preview**
- `POST /admin/analytics-admin/segment/preview`
- Payload: JSON of source + condition rows built in JS.

**Save**
- `POST /admin/analytics-admin/segment/save`
- Payload: name, description, source, conditions.

## Dashboards Tab
### Filters
- Date range dropdown (`#ba-date-range-select`) + optional custom date range inputs.
- Search button updates config attributes and triggers API fetch.
- Reset button restores defaults and re-fetches.

### Data Fetch
- Endpoint: `GET /admin/business-analytics/widgets/all-data`
- Query params:
  - `date_range_start`
  - `date_range_end`
  - `segment_filter`
  - `app_id`

### KPI Cards
- Rendered by `renderKPICards()` using element IDs:
  - `#kpi-total-revenue-value`, `#kpi-total-revenue-trend`
  - `#kpi-mrr-value`, `#kpi-mrr-trend`
  - `#kpi-arr-value`, `#kpi-arr-trend`
  - `#kpi-churn-value`, `#kpi-churn-trend`
  - `#kpi-ltv-value`, `#kpi-ltv-trend`
  - `#kpi-recovery-value`, `#kpi-recovery-trend`

### Charts (Chart.js)
- `renderCharts()` uses `data.charts` from the all-data endpoint.
- MRR & ARR: `#mrr-arr-chart` (line/area)
- Churn Rate: `#churn-recovery-chart` (line)
- Customer Segments: `#segments-chart` (pie)
- Dunning Success Rate chart is present but commented out in the script.

## Segments Tab
### Segments List + KPI Refresh
- Endpoint: `GET /admin/business-analytics/widgets/segments`
- Query params:
  - `search`
  - `filter`
  - `include_kpis=true`
  - `app_id`
- Functions:
  - `loadSegments(search, filter, forceReload)` renders cards and updates KPIs.
  - `refreshSegmentsKpiGrid()` re-fetches KPIs and segments.

### Segment Detail
- Endpoint: `GET /admin/business-analytics/widgets/segments/{segmentId}`
- Query params:
  - `page`
  - `per_page`
  - `app_id`
- Function: `loadSegmentDetail(segmentId, page)` updates detail header, table rows, and pagination.

### Cohort Toggle
- Endpoint: `POST /admin/analytics-admin/segment/{segmentId}/toggle-cohort`
- Uses modal confirm, updates segment card state, and emits a Livewire event.

### Export
- Endpoint: `GET /admin/analytics-admin/segment/{segmentId}/export/csv`
- Triggered from segment detail export menu.

## Segment Builder
- Preview endpoint: `POST /admin/analytics-admin/segment/preview`
- Save endpoint: `POST /admin/analytics-admin/segment/save`
- Builder UI uses inline state and builds a JSON payload from selected conditions.

## Saved Dashboard Section (Disabled)
- The markup exists, but logic and tab activation are mostly disabled in JS.
- Uses Livewire for listing saved dashboards, preview, and download.

## Notes / Operational Details
- Multiple loading guards prevent concurrent segment loads (`segmentsLoading`).
- Segments grid uses `data-locked` / `data-segments-loaded` to avoid redundant refresh.
- Initial dashboard fetch occurs on DOMContentLoaded and on `data-last-updated` mutations.
