import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { JwtPayload } from '../../core/login_core/login_core.service';
import { CurrentUser } from '../../gateway/auth/current_user.decorator';
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
import { CreateBlockDto, CreateReportDto, PaginationDto, SocialUserActionDto, TravelDestinationDto, UpdateSocialProfileDto } from './dto/social.dto';
import { SocialService } from './social.service';

function id(value: string): bigint {
  if (!/^\d+$/.test(String(value || ''))) throw new Error('用户标识无效');
  return BigInt(value);
}

@ApiTags('social')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('social')
export class SocialController {
  constructor(private readonly social: SocialService) {}

  @Get('interest-tags')
  interestTags() { return { success: true, data: this.social.getInterestTags() }; }

  @Patch('profile')
  async updateProfile(@CurrentUser() user: JwtPayload, @Body() body: UpdateSocialProfileDto) { return { success: true, data: await this.social.updateSocialProfile(id(user.sub), body) }; }

  @Get('profile')
  async ownProfile(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.getOwnSocialProfile(id(user.sub)) }; }

  @Get('profiles/:userId')
  async profile(@CurrentUser() user: JwtPayload, @Param('userId') userId: string) { return { success: true, data: await this.social.getPublicProfile(id(user.sub), id(userId)) }; }

  @Get('friends')
  async friends(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.getFriends(id(user.sub)) }; }

  @Get('friend-requests')
  async friendRequests(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.getFriendRequests(id(user.sub)) }; }

  @Post('friend-requests')
  async createFriendRequest(@CurrentUser() user: JwtPayload, @Body() body: SocialUserActionDto) { return { success: true, data: await this.social.createFriendRequest(id(user.sub), id(body.userId)) }; }

  @Post('friend-requests/:requestId/accept')
  async acceptFriendRequest(@CurrentUser() user: JwtPayload, @Param('requestId') requestId: string) { return { success: true, data: await this.social.acceptFriendRequest(id(user.sub), id(requestId)) }; }

  @Post('friend-requests/:requestId/reject')
  async rejectFriendRequest(@CurrentUser() user: JwtPayload, @Param('requestId') requestId: string) { await this.social.rejectFriendRequest(id(user.sub), id(requestId)); return { success: true }; }

  @Delete('friend-requests/:requestId')
  async cancelFriendRequest(@CurrentUser() user: JwtPayload, @Param('requestId') requestId: string) { await this.social.cancelFriendRequest(id(user.sub), id(requestId)); return { success: true }; }

  @Delete('friends/:userId')
  async removeFriend(@CurrentUser() user: JwtPayload, @Param('userId') userId: string) { await this.social.removeFriend(id(user.sub), id(userId)); return { success: true }; }

  @Get('blocks')
  async blocks(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.listBlocks(id(user.sub)) }; }

  @Post('blocks')
  async block(@CurrentUser() user: JwtPayload, @Body() body: CreateBlockDto) { return { success: true, data: await this.social.blockUser(id(user.sub), id(body.userId)) }; }

  @Delete('blocks/:userId')
  async unblock(@CurrentUser() user: JwtPayload, @Param('userId') userId: string) { return { success: true, data: await this.social.unblockUser(id(user.sub), id(userId)) }; }

  @Post('reports')
  async report(@CurrentUser() user: JwtPayload, @Body() body: CreateReportDto) { return { success: true, data: await this.social.createReport(id(user.sub), { userId: id(body.userId), reason: body.reason, note: body.note, messageId: body.messageId ? id(body.messageId) : undefined, blockAlso: body.blockAlso }) }; }

  @Get('conversations')
  async conversations(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.listConversations(id(user.sub)) }; }

  @Get('conversations/:userId/messages')
  async conversation(@CurrentUser() user: JwtPayload, @Param('userId') userId: string, @Query() query: PaginationDto) { return { success: true, data: await this.social.listConversation(id(user.sub), id(userId), query.limit || 30, query.before ? new Date(query.before) : undefined) }; }

  @Patch('conversations/:userId/read')
  async markConversationRead(@CurrentUser() user: JwtPayload, @Param('userId') userId: string) { return { success: true, data: await this.social.markConversationRead(id(user.sub), id(userId)) }; }

  @Get('notifications')
  async notifications(@CurrentUser() user: JwtPayload, @Query() query: PaginationDto) { return { success: true, data: await this.social.getNotificationSummary(id(user.sub), query.limit || 30, query.before ? new Date(query.before) : undefined) }; }

  @Patch('notifications/:notificationId/read')
  async markNotificationRead(@CurrentUser() user: JwtPayload, @Param('notificationId') notificationId: string) { return { success: true, data: await this.social.markNotificationRead(id(user.sub), id(notificationId)) }; }

  @Patch('notifications/read-all')
  async markAllNotificationsRead(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.markAllNotificationsRead(id(user.sub)) }; }
}

@ApiTags('world')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('world/travel-destinations')
export class WorldTravelController {
  constructor(private readonly social: SocialService) {}

  @Get()
  async destinations(@CurrentUser() user: JwtPayload) { return { success: true, data: await this.social.getTravelDestinations(id(user.sub)) }; }

  @Post(':destinationId/discover')
  async discover(@CurrentUser() user: JwtPayload, @Param('destinationId') destinationId: string) { return { success: true, data: await this.social.discoverDestination(id(user.sub), destinationId) }; }

  @Post(':destinationId/travel')
  async travel(@CurrentUser() user: JwtPayload, @Param('destinationId') destinationId: string) { return { success: true, data: await this.social.travelTo(id(user.sub), destinationId) }; }
}
