// Import necessary decorators, guards, and utilities from NestJS and Swagger
import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Put,
  UseGuards,
  ValidationPipe,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; // For Swagger documentation grouping

// Import service, DTOs, entities, and other dependencies
import { MenuGroupsService } from './menu-groups.service';
import { CreateDto } from './dto/create.dto';
import { MenuGroupsEntity } from 'src/entities/MenuGroups.entity';
import { SearchDto } from './dto/search-dto';
import { UpdateDto } from './dto/update.dto';
import { Response } from 'src/config/pagination/paginationDto'; // Custom pagination response type
import { SessionGuard } from 'src/config/guards/session.guard'; // Authentication guard
import { handleServiceRequest } from 'src/utils/response/response-handler'; // Utility for consistent error handling
import { FetchByUsersDto } from './dto/fetch-by-users.dto';
import { UpdateStatusDto } from './dto/update-status.dto';
import { SessionData, SessionDataProps } from 'src/utils/decorators'; // Custom decorator for session data

/**
 * MenuGroupsController - Handles all HTTP requests related to menu groups
 *
 * This controller provides CRUD operations and additional business logic
 * for managing menu groups in the application. It uses session-based
 * authentication and follows RESTful conventions.
 *
 * @ApiTags - Groups all endpoints under "Menu Groups" in Swagger documentation
 * @Controller - Defines this as a controller (empty string means root path for this module)
 * @UseGuards(SessionGuard) - Applies session authentication to all endpoints in this controller
 */
@ApiTags('Menu Groups')
@Controller('')
@UseGuards(SessionGuard)
export class MenuGroupsController {
  /**
   * Constructor with dependency injection for MenuGroupsService
   * @param groupService - Injected service that contains business logic
   */
  constructor(private readonly groupService: MenuGroupsService) {}

  /**
   * POST /all - Retrieves a paginated list of menu groups with search capabilities
   *
   * This endpoint supports filtering, sorting, and pagination through the SearchDto.
   * It returns a paginated response wrapped in a custom Response format.
   *
   * @param searchDto - Contains search criteria, pagination, and sorting parameters
   * @returns Promise<Response<MenuGroupsEntity>> - Paginated response containing menu groups
   */
  @Post('all')
  async findAll(
    @Body() searchDto: SearchDto,
  ): Promise<Response<MenuGroupsEntity>> {
    return await handleServiceRequest(this.groupService.findAll(searchDto));
  }

  /**
   * GET /active - Retrieves all active menu groups
   *
   * This endpoint returns only menu groups that are currently active/available.
   * Typically used for dropdowns or selection lists where only active items should appear.
   *
   * @returns Promise<Response<MenuGroupsEntity>> - List of active menu groups
   */
  @Get('active')
  async findAllActive(): Promise<Response<MenuGroupsEntity>> {
    return await handleServiceRequest(this.groupService.findAllActive());
  }

  /**
   * GET /:id - Retrieves a single menu group by ID
   *
   * @param id - The numeric ID of the menu group to retrieve
   * @returns The requested menu group entity
   */
  @Get(':id')
  async findOne(@Param('id') id: number) {
    return await handleServiceRequest(this.groupService.findOne(id));
  }

  /**
   * POST / - Creates a new menu group
   *
   * Uses ValidationPipe to automatically validate the incoming request body
   * against the CreateDto validation rules. Requires authenticated user session.
   *
   * @param body - Validated creation data from request body
   * @param sessionData - Current user's session data (extracted via custom decorator)
   * @returns Promise<MenuGroupsEntity> - The newly created menu group
   */
  @Post()
  async create(
    @Body(new ValidationPipe()) body: CreateDto,
    @SessionData() sessionData: SessionDataProps,
  ): Promise<MenuGroupsEntity> {
    return await handleServiceRequest(
      this.groupService.create(sessionData?.user?.id, body),
    );
  }

  /**
   * PUT / - Updates an existing menu group
   *
   * Uses ValidationPipe for request body validation. Requires the user to be authenticated.
   *
   * @param body - Validated update data from request body
   * @param sessionData - Current user's session data for audit tracking
   * @returns The updated menu group entity
   */
  @Put()
  async update(
    @Body(new ValidationPipe()) body: UpdateDto,
    @SessionData() sessionData: SessionDataProps,
  ) {
    return await handleServiceRequest(
      this.groupService.update(sessionData?.user?.id, body),
    );
  }

  /**
   * POST /fetch-users - Retrieves users who have created or updated menu groups
   *
   * This endpoint is useful for displaying user filters or audit purposes.
   * It helps identify which users have been involved in menu group management.
   *
   * @param params - Contains the filter type ('createdBy' or 'updatedBy')
   * @returns List of users who have created or updated menu groups
   */
  @Post('fetch-users')
  async getCreatedByOrUpdatedByUsers(
    @Body(new ValidationPipe()) params: FetchByUsersDto,
  ) {
    return await handleServiceRequest(
      this.groupService.fetchCreatedByOrUpdatedByUsers(params.by),
    );
  }

  /**
   * POST /update-status - Updates the status of a menu group
   *
   * Typically used to activate/deactivate menu groups. The status change
   * is tracked with the user who performed the action.
   *
   * @param body - Contains the menu group ID and new status value
   * @param sessionData - Current user's session data for audit purposes
   * @returns The updated menu group with new status
   */
  @Post('update-status')
  async updateStatus(
    @Body() body: UpdateStatusDto,
    @SessionData() sessionData: SessionDataProps,
  ) {
    return await handleServiceRequest(
      this.groupService.updateStatus(sessionData?.user?.id, body),
    );
  }
}
