import { Body, Controller, Get, Post, ValidationPipe } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBody } from '@nestjs/swagger';
import { CoursePortalService } from './course-portal.service';
import { SearchCoursePortalDto } from './dto/search-dto';
import { CitySearchDto } from './dto/city-search-dto';

/**
 * Course Portal Controller
 *
 * This controller handles all course portal related API endpoints.
 * The course portal is typically a section of the application where users can:
 * - Search and browse available courses
 * - Filter courses by various criteria (location, stream, etc.)
 * - Get filter options for the search interface
 * - Retrieve hierarchical data (countries → states → cities, streams → substreams)
 *
 * @ApiTags('Course Portal') - Groups all endpoints under 'Course Portal' in Swagger UI
 *
 * @example
 * // All endpoints are prefixed with the controller's path (if specified in @Controller)
 * // In this case, endpoints are at the root level (e.g., /all, /filters)
 */
@ApiTags('Course Portal')
@Controller('') // Empty path means routes are at root level (consider adding a prefix like 'course-portal')
export class CoursePortalController {
  /**
   * Constructor with dependency injection of CoursePortalService
   * @param coursePortalService - Service containing business logic for course portal operations
   */
  constructor(private readonly coursePortalService: CoursePortalService) {}

  /**
   * Search and retrieve courses with filtering and pagination
   *
   * This endpoint allows clients to search for courses with various filters
   * including release version, release date, and pagination options.
   *
   * @param searchDto - Search criteria and pagination parameters
   * @returns Paginated list of courses matching the search criteria
   *
   * @example
   * // POST /all
   * // Request Body:
   * {
   *   "release_version": "2.1.0",
   *   "release_date": "2024-01-15",
   *   "page": 1,
   *   "limit": 10
   * }
   *
   * @example
   * // Response:
   * {
   *   "data": [...], // Array of courses
   *   "meta": {
   *     "page": 1,
   *     "limit": 10,
   *     "total": 150,
   *     "totalPages": 15
   *   }
   * }
   */
  @Post('all')
  @ApiOperation({
    summary: 'Search courses with filters and pagination',
    description:
      'Returns a paginated list of courses based on search criteria including release version and date',
  })
  @ApiResponse({ status: 200, description: 'Successfully retrieved courses' })
  @ApiResponse({ status: 400, description: 'Invalid search parameters' })
  @ApiBody({ type: SearchCoursePortalDto })
  findAll(@Body() searchDto: SearchCoursePortalDto) {
    return this.coursePortalService.getSearchCourses(searchDto);
  }

  /**
   * Retrieve all available filter options for the course portal
   *
   * This endpoint returns filter options such as:
   * - Available countries
   * - Study levels
   * - Streams
   * - Intake periods
   * - Any other filterable attributes
   *
   * @returns Object containing arrays of filter options
   *
   * @example
   * // GET /filters
   * // Response:
   * {
   *   "countries": [...],
   *   "studyLevels": [...],
   *   "streams": [...],
   *   "intakes": [...],
   *   "durationTypes": [...]
   * }
   */
  @Get('filters')
  @ApiOperation({
    summary: 'Get all filter options',
    description:
      'Returns all available filter options for the course search interface',
  })
  @ApiResponse({
    status: 200,
    description: 'Successfully retrieved filter options',
  })
  fetchFilters() {
    return this.coursePortalService.getFilters();
  }

  /**
   * Get states/provinces for a list of country IDs
   *
   * This endpoint supports multi-select functionality where users can
   * select multiple countries and get all states from those countries.
   *
   * @param ids - Array of country IDs
   * @returns Array of states belonging to the specified countries
   *
   * @example
   * // POST /states-by-countries
   * // Request Body: [1, 44, 91] // USA, UK, India IDs
   * // Response: Array of states from USA, UK, and India
   */
  @Post('states-by-countries')
  @ApiOperation({
    summary: 'Get states by country IDs',
    description:
      'Returns states/provinces for the specified country IDs (supports multiple countries)',
  })
  @ApiResponse({ status: 200, description: 'Successfully retrieved states' })
  @ApiResponse({ status: 400, description: 'Invalid country IDs' })
  @ApiBody({
    description: 'Array of country IDs',
    schema: { type: 'array', items: { type: 'number' }, example: [1, 44, 91] },
  })
  fetchStatesByCountryIds(@Body() ids: number[]) {
    return this.coursePortalService.getStatesByCountryIds(ids);
  }

  /**
   * Get cities filtered by states and countries
   *
   * This endpoint allows hierarchical filtering where users can:
   * 1. Select countries → get states → select states → get cities
   * 2. Or select countries → get all cities in those countries
   *
   * @param body - Object containing countries array and optional states array
   * @returns Array of cities matching the country and state filters
   *
   * @example
   * // POST /cities-by-states-and-countries
   * // Request Body:
   * {
   *   "countries": [1], // USA
   *   "states": [5, 12] // California and Texas
   * }
   * // Response: Cities in California and Texas, USA
   */
  @Post('cities-by-states-and-countries')
  @ApiOperation({
    summary: 'Get cities by states and countries',
    description:
      'Returns cities filtered by specified countries and optionally by states',
  })
  @ApiResponse({ status: 200, description: 'Successfully retrieved cities' })
  @ApiResponse({ status: 400, description: 'Invalid input data' })
  @ApiBody({ type: CitySearchDto })
  fetchCitiesByStatesAndCountries(
    @Body(new ValidationPipe()) body: CitySearchDto,
  ) {
    return this.coursePortalService.getCitiesByStatesAndCountries(body);
  }

  /**
   * Get sub-streams (specializations) for a list of streams
   *
   * This endpoint supports the hierarchical relationship:
   * Streams (e.g., Engineering) → Sub-streams (e.g., Mechanical, Electrical, Civil)
   *
   * @param streams - Array of stream IDs
   * @returns Array of sub-streams belonging to the specified streams
   *
   * @example
   * // POST /substreams-by-streams
   * // Request Body: [1, 3] // Engineering and Business IDs
   * // Response: Sub-streams for Engineering and Business
   */
  @Post('substreams-by-streams')
  @ApiOperation({
    summary: 'Get sub-streams by stream IDs',
    description:
      'Returns sub-streams/specializations for the specified stream IDs',
  })
  @ApiResponse({
    status: 200,
    description: 'Successfully retrieved sub-streams',
  })
  @ApiResponse({ status: 400, description: 'Invalid stream IDs' })
  @ApiBody({
    description: 'Array of stream IDs',
    schema: { type: 'array', items: { type: 'number' }, example: [1, 3] },
  })
  fetchSubStreamsByStreams(@Body() streams: number[]) {
    return this.coursePortalService.getSubStreamsByStreams(streams);
  }
}
