import { Controller, Get, Put, Body, UseGuards, Logger, Param, ParseIntPipe } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBody, ApiParam } from '@nestjs/swagger';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { Roles } from 'common/decorators/role.decorator';
import { UserRole } from 'common/enum/UserRole.enum';
import { UpdateSettingDto } from './dto/update-setting.dto';
import { UpdateUserSettingDto } from './dto/update-user-setting.dto';
import { Setting } from './entity/setting.entity';
import { UserSetting } from './entity/user-setting.entity';
import { SettingsService } from './setting.services';


@ApiTags('Settings')
@Controller({ path: 'settings', version: '1' })
@UseGuards(JwtAuthGuard)
@Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN)
export class SettingsController {
  private readonly logger = new Logger(SettingsController.name);

  constructor(private readonly settingsService: SettingsService) { }

  @Get('global')
  @ApiOperation({ summary: 'Get all global application settings' })
  @ApiResponse({ status: 200, description: 'List of all global settings.', type: [Setting] })
  async getAllGlobalSettings(): Promise<Setting[]> {
    this.logger.log('Fetching all global settings');
    return this.settingsService.getAllGlobalSettings();
  }

  @Put('global')
  @ApiOperation({ summary: 'Create or update a global application setting' })
  @ApiBody({ type: UpdateSettingDto })
  @ApiResponse({ status: 200, description: 'Global setting updated successfully.', type: Setting })
  async updateGlobalSetting(@Body() updateSettingDto: UpdateSettingDto): Promise<Setting> {
    this.logger.log(`Request to update global setting: ${updateSettingDto.key}`);
    return this.settingsService.updateGlobalSetting(updateSettingDto);
  }

  @Get('user/:userId')
  @ApiOperation({ summary: 'Get all setting overrides for a specific user' })
  @ApiParam({ name: 'userId', description: 'The ID of the user', type: 'number' })
  @ApiResponse({ status: 200, description: 'List of setting overrides for the user.', type: [UserSetting] })
  async getSettingsForUser(@Param('userId', ParseIntPipe) userId: number): Promise<UserSetting[]> {
    this.logger.log(`Fetching settings for user ID: ${userId}`);
    return this.settingsService.getSettingsForUser(userId);
  }

  @Put('user')
  @ApiOperation({ summary: 'Create or update a setting override for a specific user' })
  @ApiBody({ type: UpdateUserSettingDto })
  @ApiResponse({ status: 200, description: 'User-specific setting updated successfully.', type: UserSetting })
  async updateUserSetting(@Body() updateUserSettingDto: UpdateUserSettingDto): Promise<UserSetting> {
    this.logger.log(`Request to update setting for user: ${updateUserSettingDto.userId}`);
    return this.settingsService.updateUserSetting(updateUserSettingDto);
  }

  @Get()
  @ApiOperation({ summary: 'Get all settings (global and user-specific)' })
  @ApiResponse({
    status: 200,
    description: 'All settings organized by type.',
    schema: {
      type: 'object',
      properties: {
        globalSettings: {
          type: 'array',
          items: { $ref: '#/components/schemas/Setting' }
        },
        userSettings: {
          type: 'array',
          items: { $ref: '#/components/schemas/UserSetting' }
        }
      }
    }
  })
  async getAllSettings(): Promise<{
    globalSettings: Setting[];
    userSettings: UserSetting[];
  }> {
    this.logger.log('Fetching all settings (global and user-specific)');
    return this.settingsService.getAllSettings();
  }

  @Get('keys')
  @ApiOperation({ summary: 'Get list of available setting key names' })
  @ApiResponse({
    status: 200,
    description: 'List of available setting keys.',
    schema: {
      type: 'array',
      items: {
        type: 'string'
      },
      example: ['MAX_ORGS_PER_USER', 'MAX_WEBSITES_PER_ORG']
    }
  })
  async getSettingKeyNames(): Promise<string[]> {
    this.logger.log('Fetching setting key names');
    return this.settingsService.getSettingKeyName();
  }

}