import { Controller, Get, Query, Req, UseGuards } from '@nestjs/common';
import { Request } from 'express';
import { DashboardService } from './dashboard.service';
import { DashboardQueryDto } from './dto/dashboard-query.dto';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import { Permissions } from '../../auth/decorators/permissions.decorator';
import { AccessLevel, ModuleName } from '../../entities/role-permission.entity';
import { successResponse } from '../../common/responses/api-response';

@Controller('dashboard')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class DashboardController {
  constructor(private readonly service: DashboardService) {}

  /**
   * Tenant-wide KPIs for the Admin dashboard only. Gated on
   * BOOKING:delete (same discriminator as full row visibility) so
   * custom / sales roles cannot pull company-wide numbers via API.
   */
  @Get('stats')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.DELETE })
  async getStats(@Query() query: DashboardQueryDto) {
    const data = await this.service.getStats(
      query.start_date,
      query.end_date,
      query.destination_id,
    );
    return successResponse(data, 'Dashboard stats fetched successfully');
  }

  /**
   * Sales Head — team-wide funnel, aging, source mix, turnaround.
   * Gated by QUERY:edit so only Admin + Sales Head can see team
   * aggregates; Sales Team users land here via /dashboard/sales-team
   * with their own data instead.
   */
  @Get('sales-head')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.EDIT })
  async getSalesHeadStats(@Query() query: DashboardQueryDto) {
    const data = await this.service.getSalesHeadStats(
      query.start_date,
      query.end_date,
      query.destination_id,
    );
    return successResponse(data, 'Sales head stats fetched successfully');
  }

  /**
   * Sales Team — per-user "My X" cards. JWT-only because the user
   * sees only their own pipeline; tenant scoping happens inside the
   * service via CLS.
   */
  @Get('sales-team')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async getSalesTeamStats(@Query() query: DashboardQueryDto, @Req() req: Request) {
    const userId = (req as Request & { user: { id: string } }).user.id;
    const data = await this.service.getSalesTeamStats(
      userId,
      query.start_date,
      query.end_date,
      query.destination_id,
    );
    return successResponse(data, 'Sales team stats fetched successfully');
  }

  /**
   * Ops Manager — operational execution today / tomorrow. Gated by
   * BOOKING:view since the cards expose booking-level operational
   * data; every role with booking visibility can see it. The page
   * filter is intentionally not consumed — Ops cards are always
   * relative to "now".
   */
  @Get('ops')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async getOpsStats(@Query() query: DashboardQueryDto) {
    const data = await this.service.getOpsStats(query.destination_id);
    return successResponse(data, 'Ops stats fetched successfully');
  }

  /**
   * Trip Coordinator — same shape as Ops but scoped to the caller's
   * own bookings (created_by OR query.sales_team membership). JWT
   * only — the data is already self-scoped.
   */
  @Get('trip-coordinator')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async getTripCoordinatorStats(@Req() req: Request, @Query() query: DashboardQueryDto) {
    const userId = (req as Request & { user: { id: string } }).user.id;
    const data = await this.service.getTripCoordinatorStats(userId, query.destination_id);
    return successResponse(data, 'Trip coordinator stats fetched successfully');
  }
}
