# Analytics Service

Comprehensive financial and analytical intelligence service for the Clinic Admin app. Provides insights about doctors, procedures, appointments, patients, products, and clinic operations.

## Overview

The `AnalyticsService` extends `BaseService` and provides methods to analyze appointment data, calculate metrics, and generate reports for clinic administration.

## Usage

### Initialization

```typescript
import { AnalyticsService } from '@blackcode_sa/metaestetics-api';
import { AppointmentService } from '@blackcode_sa/metaestetics-api';

// Initialize dependencies
const appointmentService = new AppointmentService(db, auth, app, ...);

// Initialize analytics service
const analyticsService = new AnalyticsService(db, auth, app, appointmentService);
```

## Available Methods

### ⚡ **Grouped Analytics** (NEW!)

All analytics now support **consistent grouping** by clinic, practitioner, procedure, patient, or technology:

- `getRevenueMetricsByEntity(groupBy, dateRange?, filters?)` - Revenue by entity
- `getProductUsageMetricsByEntity(groupBy, dateRange?, filters?)` - Product usage by entity
- `getTimeEfficiencyMetricsByEntity(groupBy, dateRange?, filters?)` - Time efficiency by entity
- `getPatientBehaviorMetricsByEntity(groupBy, dateRange?, filters?)` - Patient behavior by entity
- `getCancellationMetrics(groupBy, dateRange?)` - Cancellations by entity (existing)
- `getNoShowMetrics(groupBy, dateRange?)` - No-shows by entity (existing)

**Technology Grouping**: Groups all procedures using the same technology across all doctors (e.g., all Botox treatments regardless of which doctor performed them).

**See [GROUPED_ANALYTICS.md](./GROUPED_ANALYTICS.md) for complete guide and examples.**

### Practitioner Analytics

#### `getPractitionerAnalytics(practitionerId, dateRange?)`

Get comprehensive performance metrics for a practitioner.

**Returns**: `PractitionerAnalytics`

**Example**:
```typescript
const metrics = await analyticsService.getPractitionerAnalytics(
  'practitioner-id-123',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

console.log(`Total appointments: ${metrics.totalAppointments}`);
console.log(`Cancellation rate: ${metrics.cancellationRate}%`);
console.log(`Total revenue: ${metrics.totalRevenue} ${metrics.currency}`);
```

### Procedure Analytics

#### `getProcedureAnalytics(procedureId?, dateRange?)`

Get performance metrics for one or all procedures.

**Returns**: `ProcedureAnalytics | ProcedureAnalytics[]`

**Example**:
```typescript
// Get analytics for a specific procedure
const procedureMetrics = await analyticsService.getProcedureAnalytics(
  'procedure-id-123',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

// Get analytics for all procedures
const allProcedures = await analyticsService.getProcedureAnalytics(
  undefined,
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);
```

#### `getProcedurePopularity(dateRange?, limit?)`

Get the most popular procedures by appointment count.

**Returns**: `ProcedurePopularity[]`

**Example**:
```typescript
const topProcedures = await analyticsService.getProcedurePopularity(
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') },
  10 // Top 10 procedures
);
```

#### `getProcedureProfitability(dateRange?, limit?)`

Get the most profitable procedures by revenue.

**Returns**: `ProcedureProfitability[]`

**Example**:
```typescript
const profitableProcedures = await analyticsService.getProcedureProfitability(
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') },
  10
);
```

### Time Efficiency Analytics

#### `getTimeEfficiencyMetrics(filters?, dateRange?)`

Analyze booked time vs actual time spent on appointments.

**Returns**: `TimeEfficiencyMetrics`

**Example**:
```typescript
const timeMetrics = await analyticsService.getTimeEfficiencyMetrics(
  { clinicBranchId: 'clinic-123' },
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

console.log(`Average efficiency: ${timeMetrics.averageEfficiency}%`);
console.log(`Average overrun: ${timeMetrics.averageOverrun} minutes`);
```

### Cancellation & No-Show Analytics

#### `getCancellationMetrics(groupBy, dateRange?)`

Get cancellation metrics grouped by clinic, practitioner, patient, or procedure.

**Returns**: `CancellationMetrics | CancellationMetrics[]`

**Example**:
```typescript
// Get cancellations by clinic
const clinicCancellations = await analyticsService.getCancellationMetrics(
  'clinic',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

// Get cancellations by practitioner
const practitionerCancellations = await analyticsService.getCancellationMetrics(
  'practitioner',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);
```

#### `getNoShowMetrics(groupBy, dateRange?)`

Get no-show metrics grouped by clinic, practitioner, patient, or procedure.

**Returns**: `NoShowMetrics | NoShowMetrics[]`

**Example**:
```typescript
const noShowMetrics = await analyticsService.getNoShowMetrics(
  'patient',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);
```

### Financial Analytics

#### `getRevenueMetrics(filters?, dateRange?)`

Get comprehensive revenue metrics.

**Returns**: `RevenueMetrics`

**Example**:
```typescript
const revenue = await analyticsService.getRevenueMetrics(
  { clinicBranchId: 'clinic-123' },
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

console.log(`Total revenue: ${revenue.totalRevenue} ${revenue.currency}`);
console.log(`Unpaid revenue: ${revenue.unpaidRevenue}`);
```

### Product Usage Analytics

#### `getProductUsageMetrics(productId?, dateRange?)`

Get product usage metrics for one or all products.

**Returns**: `ProductUsageMetrics | ProductUsageMetrics[]`

**Example**:
```typescript
// Get usage for a specific product
const productMetrics = await analyticsService.getProductUsageMetrics(
  'product-id-123',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

// Get usage for all products
const allProducts = await analyticsService.getProductUsageMetrics(
  undefined,
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);
```

### Patient Analytics

#### `getPatientAnalytics(patientId?, dateRange?)`

Get analytics for one or all patients.

**Returns**: `PatientAnalytics | PatientAnalytics[]`

**Example**:
```typescript
const patientMetrics = await analyticsService.getPatientAnalytics(
  'patient-id-123',
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

console.log(`Lifetime value: ${patientMetrics.lifetimeValue}`);
console.log(`Average days between appointments: ${patientMetrics.averageDaysBetweenAppointments}`);
```

### Dashboard Analytics

#### `getDashboardData(filters?, dateRange?)`

Get comprehensive dashboard data aggregation.

**Returns**: `DashboardAnalytics`

**Example**:
```typescript
const dashboard = await analyticsService.getDashboardData(
  { clinicBranchId: 'clinic-123' },
  { start: new Date('2024-01-01'), end: new Date('2024-12-31') }
);

console.log(`Total appointments: ${dashboard.overview.totalAppointments}`);
console.log(`Total revenue: ${dashboard.overview.totalRevenue}`);
console.log(`Top practitioners:`, dashboard.practitionerMetrics);
```

## Cost Calculation Priority

The service calculates appointment costs using the following priority:

1. **`metadata.finalbilling.finalPrice`** - If available, uses the final billing price
2. **`metadata.zonesData`** - Calculates from zone item subtotals
3. **`appointment.cost`** - Falls back to base appointment cost

## Time Efficiency Calculation

Time efficiency is calculated as:
- **Booked Duration**: `appointmentEndTime - appointmentStartTime` (minutes)
- **Actual Duration**: `actualDurationMinutes` or booked duration if not available
- **Efficiency**: `(actualDuration / bookedDuration) * 100` (percentage)
- **Overrun**: Positive difference if actual > booked
- **Underutilization**: Positive difference if booked > actual

## Status Filtering

The service filters appointments by status:

- **Completed**: `AppointmentStatus.COMPLETED`
- **Canceled**: `CANCELED_PATIENT`, `CANCELED_CLINIC`, `CANCELED_PATIENT_RESCHEDULED`
- **No-Show**: `AppointmentStatus.NO_SHOW`
- **Active**: All statuses except canceled and no-show

## Performance Considerations

- The service uses the `AppointmentService` to query appointments efficiently
- Large date ranges may require pagination (to be implemented)
- Consider caching dashboard data for frequently accessed metrics
- Use specific filters to reduce query scope when possible

### Trend Analysis (NEW!)

Analyze metrics over time with period-over-period comparisons:

- `getRevenueTrends(dateRange, period, filters?, groupBy?)` - Revenue trends
- `getDurationTrends(dateRange, period, filters?, groupBy?)` - Time efficiency trends
- `getAppointmentTrends(dateRange, period, filters?, groupBy?)` - Appointment volume trends
- `getCancellationRateTrends(dateRange, period, filters?, groupBy?)` - Cancellation/no-show rate trends

**Period Types**: Week, Month, Quarter, Year

**Features**: Percentage change calculations, direction indicators (up/down/stable), grouped trends

**See [TRENDS.md](./TRENDS.md) for complete guide and examples.**

## Related Documentation

- [Analytics Types](../../types/analytics/analytics.types.ts)
- [Grouped Analytics Guide](./GROUPED_ANALYTICS.md)
- [Trend Analysis Guide](./TRENDS.md)
- [Appointment Service](../appointment/README.md)
- [Full Proposal](../../backoffice/services/analytics.service.proposal.md)

