import {
  Controller,
  Get,
  Post,
  Delete,
  Param,
  Body,
  Query,
  UseGuards,
  HttpCode,
  HttpStatus,
} from '@nestjs/common'
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger'
import { AuthorizationApplicationService } from '@/application/services'
import {
  ApplyCommunityAuthCommand,
  ApplyAuthProvinceCompanyCommand,
  ApplyAuthCityCompanyCommand,
  RevokeAuthorizationCommand,
  GrantMonthlyBypassCommand,
  ExemptLocalPercentageCheckCommand,
  SelfApplyAuthorizationCommand,
} from '@/application/commands'
import {
  ApplyCommunityAuthDto,
  ApplyAuthProvinceDto,
  ApplyAuthCityDto,
  RevokeAuthorizationDto,
  GrantMonthlyBypassDto,
  SelfApplyAuthorizationDto,
  SelfApplyAuthorizationResponseDto,
  UserAuthorizationStatusResponseDto,
  SelfApplyAuthorizationType,
} from '@/api/dto/request'
import {
  AuthorizationResponse,
  ApplyAuthorizationResponse,
  StickmanRankingResponse,
  CommunityHierarchyResponse,
  UserProfilePublicResponse,
  UserProfilePrivateResponse,
} from '@/api/dto/response'
import { CurrentUser } from '@/shared/decorators'
import { JwtAuthGuard } from '@/shared/guards'
import { RoleType } from '@/domain/enums'

@ApiTags('Authorization')
@Controller('authorizations')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class AuthorizationController {
  constructor(private readonly applicationService: AuthorizationApplicationService) {}

  @Post('community')
  @ApiOperation({ summary: '申请社区授权' })
  @ApiResponse({ status: 201, type: ApplyAuthorizationResponse })
  async applyCommunityAuth(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: ApplyCommunityAuthDto,
  ): Promise<ApplyAuthorizationResponse> {
    const command = new ApplyCommunityAuthCommand(user.userId, user.accountSequence, dto.communityName)
    return await this.applicationService.applyCommunityAuth(command)
  }

  @Post('province')
  @ApiOperation({ summary: '申请授权省公司' })
  @ApiResponse({ status: 201, type: ApplyAuthorizationResponse })
  async applyAuthProvinceCompany(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: ApplyAuthProvinceDto,
  ): Promise<ApplyAuthorizationResponse> {
    const command = new ApplyAuthProvinceCompanyCommand(
      user.userId,
      user.accountSequence,
      dto.provinceCode,
      dto.provinceName,
    )
    return await this.applicationService.applyAuthProvinceCompany(command)
  }

  @Post('city')
  @ApiOperation({ summary: '申请授权市公司' })
  @ApiResponse({ status: 201, type: ApplyAuthorizationResponse })
  async applyAuthCityCompany(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: ApplyAuthCityDto,
  ): Promise<ApplyAuthorizationResponse> {
    const command = new ApplyAuthCityCompanyCommand(user.userId, user.accountSequence, dto.cityCode, dto.cityName)
    return await this.applicationService.applyAuthCityCompany(command)
  }

  @Get('my')
  @ApiOperation({ summary: '获取我的授权列表' })
  @ApiResponse({ status: 200, type: [AuthorizationResponse] })
  async getMyAuthorizations(
    @CurrentUser() user: { userId: string; accountSequence: string },
  ): Promise<AuthorizationResponse[]> {
    return await this.applicationService.getUserAuthorizations(user.accountSequence)
  }

  @Get('my/community-hierarchy')
  @ApiOperation({ summary: '获取我的社区层级（上级社区和下级社区）' })
  @ApiResponse({ status: 200, type: CommunityHierarchyResponse })
  async getMyCommunityHierarchy(
    @CurrentUser() user: { userId: string; accountSequence: string },
  ): Promise<CommunityHierarchyResponse> {
    return await this.applicationService.getCommunityHierarchy(user.accountSequence)
  }

  @Get(':id')
  @ApiOperation({ summary: '获取授权详情' })
  @ApiParam({ name: 'id', description: '授权ID' })
  @ApiResponse({ status: 200, type: AuthorizationResponse })
  async getAuthorizationById(@Param('id') id: string): Promise<AuthorizationResponse | null> {
    return await this.applicationService.getAuthorizationById(id)
  }

  @Get('ranking/stickman')
  @ApiOperation({ summary: '获取火柴人排名' })
  @ApiQuery({ name: 'month', description: '月份 (YYYY-MM)', example: '2024-01' })
  @ApiQuery({ name: 'roleType', description: '角色类型', enum: RoleType })
  @ApiQuery({ name: 'regionCode', description: '区域代码' })
  @ApiResponse({ status: 200, type: [StickmanRankingResponse] })
  async getStickmanRanking(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Query('month') month: string,
    @Query('roleType') roleType: RoleType,
    @Query('regionCode') regionCode: string,
  ): Promise<StickmanRankingResponse[]> {
    return await this.applicationService.getStickmanRanking(month, roleType, regionCode, user.userId)
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '撤销授权（管理员）' })
  @ApiParam({ name: 'id', description: '授权ID' })
  @ApiResponse({ status: 204 })
  async revokeAuthorization(
    @Param('id') id: string,
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: RevokeAuthorizationDto,
  ): Promise<void> {
    const command = new RevokeAuthorizationCommand(id, user.accountSequence, dto.reason)
    await this.applicationService.revokeAuthorization(command)
  }

  @Post(':id/bypass')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '授予单月豁免（管理员）' })
  @ApiParam({ name: 'id', description: '授权ID' })
  @ApiResponse({ status: 204 })
  async grantMonthlyBypass(
    @Param('id') id: string,
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: GrantMonthlyBypassDto,
  ): Promise<void> {
    const command = new GrantMonthlyBypassCommand(id, dto.month, user.accountSequence, dto.reason)
    await this.applicationService.grantMonthlyBypass(command)
  }

  @Post(':id/exempt-percentage')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '豁免占比考核（管理员）' })
  @ApiParam({ name: 'id', description: '授权ID' })
  @ApiResponse({ status: 204 })
  async exemptLocalPercentageCheck(
    @Param('id') id: string,
    @CurrentUser() user: { userId: string; accountSequence: string },
  ): Promise<void> {
    const command = new ExemptLocalPercentageCheckCommand(id, user.accountSequence)
    await this.applicationService.exemptLocalPercentageCheck(command)
  }

  // ============================================
  // 自助申请授权相关接口
  // ============================================

  @Get('self-apply/status')
  @ApiOperation({
    summary: '获取用户授权申请状态',
    description: '获取用户是否已认种、认种棵数、已有授权和待审核申请',
  })
  @ApiResponse({ status: 200, type: UserAuthorizationStatusResponseDto })
  async getUserAuthorizationStatus(
    @CurrentUser() user: { userId: string; accountSequence: string },
  ): Promise<UserAuthorizationStatusResponseDto> {
    return await this.applicationService.getUserAuthorizationStatus(user.accountSequence)
  }

  @Post('self-apply')
  @ApiOperation({
    summary: '自助申请授权',
    description: '用户自助申请社区、市团队或省团队授权（需先认种并上传办公室照片）',
  })
  @ApiResponse({ status: 201, type: SelfApplyAuthorizationResponseDto })
  async selfApplyAuthorization(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Body() dto: SelfApplyAuthorizationDto,
  ): Promise<SelfApplyAuthorizationResponseDto> {
    const command = new SelfApplyAuthorizationCommand(
      user.userId,
      user.accountSequence,
      dto.type,
      dto.officePhotoUrls,
      dto.communityName,
      dto.provinceCode,
      dto.provinceName,
      dto.cityCode,
      dto.cityName,
    )
    return await this.applicationService.selfApplyAuthorization(command)
  }

  // ============================================
  // 用户资料相关接口
  // ============================================

  @Get('users/:accountSequence/profile')
  @ApiOperation({
    summary: '获取用户公开资料',
    description: '获取指定用户的公开资料，包括昵称、头像、注册时间、推荐人、直推人数、伞下用户数、认种数量、授权列表等',
  })
  @ApiParam({ name: 'accountSequence', description: '目标用户的账户序列号' })
  @ApiResponse({ status: 200, type: UserProfilePublicResponse })
  async getUserProfile(
    @Param('accountSequence') accountSequence: string,
  ): Promise<UserProfilePublicResponse> {
    return await this.applicationService.getUserPublicProfile(accountSequence)
  }

  @Get('users/:accountSequence/profile/private')
  @ApiOperation({
    summary: '获取用户私密资料',
    description: '获取指定用户的私密资料（需要省团队以上权限），包括脱敏的手机号、邮箱、真实姓名等',
  })
  @ApiParam({ name: 'accountSequence', description: '目标用户的账户序列号' })
  @ApiResponse({ status: 200, type: UserProfilePrivateResponse })
  async getUserPrivateProfile(
    @CurrentUser() user: { userId: string; accountSequence: string },
    @Param('accountSequence') accountSequence: string,
  ): Promise<UserProfilePrivateResponse> {
    return await this.applicationService.getUserPrivateProfile(user.accountSequence, accountSequence)
  }
}
