import { Controller, Post, Get, Put, Delete, Body, UseGuards, Req, Param, Query, HttpException, HttpStatus, ParseIntPipe } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { AdminService } from './admin.service';
import { AdminGuard } from './admin.guard';
import { CoursesService } from '../courses/courses.service';
import { PrismaService } from '../../prisma/prisma.service';
import { AIGatewayService } from '../ai/ai-gateway.service';
import { AdminAiAssistantService } from './ai-assistant.service';
import { GatewayPayService } from '../payment/gateway-pay.service';

@ApiTags('管理后台')
@Controller('admin')
export class AdminController {
  constructor(
    private adminService: AdminService,
    private coursesService: CoursesService,
    private prisma: PrismaService,
    private aiGateway: AIGatewayService,
    private aiAssistant: AdminAiAssistantService,
    private gatewayPay: GatewayPayService,
  ) {}

  @Post('login')
  async login(@Body() body: { username: string; password: string }) {
    return this.adminService.login(body.username, body.password);
  }

  @Get('dashboard')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async dashboard() {
    return this.adminService.getDashboard();
  }

  @Get('orders')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async orders(
    @Query('page') page?: string,
    @Query('pageSize') pageSize?: string,
    @Query('search') search?: string,
    @Query('status') status?: string,
    @Query('payChannel') payChannel?: string,
    @Query('planType') planType?: string,
  ) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const skip = (p - 1) * ps;

    const where: any = {};
    if (status) where.status = status;
    if (payChannel) where.payChannel = payChannel;
    if (planType) where.planType = planType;
    if (search) {
      where.OR = [
        { orderNo: { contains: search } },
        { user: { nickname: { contains: search } } },
        { user: { phone: { contains: search } } },
      ];
    }

    const [items, total] = await Promise.all([
      this.prisma.order.findMany({
        where,
        orderBy: { createdAt: 'desc' },
        skip,
        take: ps,
        include: { user: { select: { id: true, nickname: true, phone: true } } },
      }),
      this.prisma.order.count({ where }),
    ]);

    return { items, total, page: p, pageSize: ps };
  }

  @Get('orders/:orderNo')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async orderDetail(@Param('orderNo') orderNo: string) {
    const order = await this.prisma.order.findUnique({
      where: { orderNo },
      include: { user: { select: { id: true, nickname: true, phone: true, email: true, memberPlan: true, memberExpire: true } } },
    });
    if (!order) throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);
    return order;
  }

  @Post('orders/:orderNo/refund')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async orderRefund(@Param('orderNo') orderNo: string, @Body() body: { amount?: number; reason?: string }) {
    const order = await this.prisma.order.findUnique({ where: { orderNo } });
    if (!order) throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);
    if (order.status !== 'PAID') throw new HttpException('订单未支付，无法退款', HttpStatus.BAD_REQUEST);

    return this.gatewayPay.refund(orderNo, body.amount || order.amount, body.reason);
  }

  @Post('orders/:orderNo/mark-paid')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async markOrderPaid(@Param('orderNo') orderNo: string) {
    const order = await this.prisma.order.findUnique({ where: { orderNo } });
    if (!order) throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);
    if (order.status !== 'PENDING') throw new HttpException('只能标记待支付订单为已支付', HttpStatus.BAD_REQUEST);

    await this.prisma.order.update({
      where: { id: order.id },
      data: { status: 'PAID', paidAt: new Date(), transactionId: `MANUAL_${Date.now()}` },
    });

    // 激活订阅
    const mockOrder = { planType: order.planType, amount: order.amount };
    if (mockOrder.planType === 'MONTHLY' || mockOrder.planType === 'YEARLY') {
      const durationDays = mockOrder.planType === 'MONTHLY' ? 30 : 365;
      const now = new Date();
      let endDate: Date;
      const existingSub = await this.prisma.subscription.findFirst({
        where: { userId: order.userId, status: 'ACTIVE', endDate: { gt: now } },
      });
      if (existingSub) {
        endDate = new Date(existingSub.endDate.getTime() + durationDays * 24 * 60 * 60 * 1000);
        await this.prisma.subscription.update({ where: { id: existingSub.id }, data: { endDate } });
      } else {
        endDate = new Date(now);
        endDate.setDate(endDate.getDate() + durationDays);
        await this.prisma.subscription.create({
          data: { userId: order.userId, plan: order.planType as any, startDate: now, endDate, status: 'ACTIVE' },
        });
      }
      await this.prisma.user.update({
        where: { id: order.userId },
        data: { memberPlan: order.planType as any, memberExpire: endDate },
      });
    }

    return { ok: true, message: '订单已标记为已支付' };
  }

  @Get('orders/:orderNo/query')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async queryOrderPayment(@Param('orderNo') orderNo: string) {
    const order = await this.prisma.order.findUnique({ where: { orderNo } });
    if (!order) throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);

    if (order.gatewayOrderId && !order.gatewayOrderId.startsWith('mock_')) {
      return this.gatewayPay.queryOrder(order.gatewayOrderId);
    }
    return {
      outTradeNo: orderNo,
      localStatus: order.status,
      amount: order.amount,
      planType: order.planType,
    };
  }

  @Put('courses/:id/chapters')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updateCourseChapters(@Param('id') id: string, @Body() body: any) {
    return this.coursesService.updateWithChapters(+id, body);
  }

  @Get('comments/pending')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async pendingComments() {
    const items = await this.prisma.comment.findMany({
      where: { status: 'PENDING_REVIEW' },
      include: {
        user: { select: { id: true, nickname: true, avatar: true } },
        post: { select: { id: true, title: true } },
      },
      orderBy: { createdAt: 'desc' },
      take: 50,
    });
    return { items };
  }

  @Put('comments/:id/approve')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async approveComment(@Param('id') id: string) {
    await this.prisma.comment.update({
      where: { id: parseInt(id) },
      data: { status: 'PUBLISHED', reviewedAt: new Date() },
    });
    return { ok: true };
  }

  @Put('comments/:id/reject')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async rejectComment(@Param('id') id: string, @Body() body: { reason?: string }) {
    await this.prisma.comment.update({
      where: { id: parseInt(id) },
      data: { status: 'REJECTED', reviewNote: body.reason || '违规内容', reviewedAt: new Date() },
    });
    return { ok: true };
  }

  @Post('ai-assistant/chat')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async aiAssistantChat(@Body() body: { messages: { role: string; content: string }[] }) {
    try {
      const { messages } = body;
      const apiMessages = messages.map(m => ({ role: m.role as 'user' | 'assistant' | 'system', content: m.content }));
      const reply = await this.aiGateway.chat('general', apiMessages, { temperature: 0.7, max_tokens: 2000 });
      return { reply };
    } catch (err: any) {
      throw new HttpException(err.message || 'AI 助手请求失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Post('ai-assistant/action')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async aiAssistantAction(@Body() body: { tool: string; params: Record<string, any>; messages: { role: string; content: string }[] }) {
    const result = await this.aiAssistant.execute({ tool: body.tool, params: body.params });
    try {
      const apiMessages = [
        { role: 'system' as const, content: '你是一个管理后台助手。下面是对用户请求的执行结果，请用自然语言总结给用户，语言简洁。' },
        ...body.messages.map(m => ({ role: m.role as 'user' | 'assistant', content: m.content })),
        { role: 'assistant' as const, content: `【工具执行结果】\n工具: ${body.tool}\n参数: ${JSON.stringify(body.params)}\n结果: ${result.summary}\n数据: ${JSON.stringify(result.data)}` },
      ];
      const reply = await this.aiGateway.chat('general', apiMessages, { temperature: 0.3, max_tokens: 1000 });
      return { reply, result };
    } catch {
      return { reply: result.summary, result };
    }
  }

  // --- Practice Questions Admin ---
  @Get('practices')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminPractices(@Query('page') page?: string, @Query('pageSize') pageSize?: string, @Query('search') search?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const where: any = {};
    if (search) where.title = { contains: search };
    const [items, total] = await Promise.all([
      this.prisma.practiceQuestion.findMany({ where, orderBy: { sortOrder: 'asc' }, skip: (p - 1) * ps, take: ps }),
      this.prisma.practiceQuestion.count({ where }),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Get('practices/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminPractice(@Param('id', ParseIntPipe) id: number) {
    const item = await this.prisma.practiceQuestion.findUnique({ where: { id } });
    if (!item) throw new HttpException('练习题目不存在', HttpStatus.NOT_FOUND);
    return item;
  }

  @Post('practices')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async createPractice(@Body() body: any) {
    const item = await this.prisma.practiceQuestion.create({ data: body });
    return item;
  }

  @Put('practices/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updatePractice(@Param('id', ParseIntPipe) id: number, @Body() body: any) {
    const { id: _id, ...data } = body;
    const item = await this.prisma.practiceQuestion.update({ where: { id }, data });
    return item;
  }

  @Delete('practices/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async deletePractice(@Param('id', ParseIntPipe) id: number) {
    await this.prisma.practiceQuestion.delete({ where: { id } });
    return { ok: true };
  }

  // --- Skills Admin ---
  @Get('skills')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminSkills(@Query('page') page?: string, @Query('pageSize') pageSize?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const [items, total] = await Promise.all([
      this.prisma.skill.findMany({ orderBy: { sortOrder: 'asc' }, skip: (p - 1) * ps, take: ps }),
      this.prisma.skill.count(),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Get('skills/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminSkill(@Param('id') id: string) {
    const item = await this.prisma.skill.findUnique({ where: { id } });
    if (!item) throw new HttpException('技能不存在', HttpStatus.NOT_FOUND);
    return item;
  }

  @Put('skills/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updateSkill(@Param('id') id: string, @Body() body: any) {
    const { id: _id, purchasedBy, ...data } = body;
    const item = await this.prisma.skill.update({ where: { id }, data });
    return item;
  }

  // --- Circles Admin ---
  @Get('circles')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminCircles(@Query('page') page?: string, @Query('pageSize') pageSize?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const [items, total] = await Promise.all([
      this.prisma.circle.findMany({ orderBy: { createdAt: 'desc' }, skip: (p - 1) * ps, take: ps, include: { creator: { select: { id: true, nickname: true } }, _count: { select: { members: true, posts: true } } } }),
      this.prisma.circle.count(),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Delete('circles/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async deleteCircle(@Param('id', ParseIntPipe) id: number) {
    await this.prisma.circle.delete({ where: { id } });
    return { ok: true };
  }

  // --- Community Posts Admin ---
  @Get('posts')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminPosts(@Query('page') page?: string, @Query('pageSize') pageSize?: string, @Query('status') status?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const where: any = {};
    if (status) where.status = status;
    const [items, total] = await Promise.all([
      this.prisma.post.findMany({
        where, orderBy: { createdAt: 'desc' }, skip: (p - 1) * ps, take: ps,
        include: { user: { select: { id: true, nickname: true } }, _count: { select: { comments: true, likes: true } } },
      }),
      this.prisma.post.count({ where }),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Get('posts/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminPost(@Param('id', ParseIntPipe) id: number) {
    const item = await this.prisma.post.findUnique({
      where: { id },
      include: { user: { select: { id: true, nickname: true } }, _count: { select: { comments: true, likes: true } } },
    });
    if (!item) throw new HttpException('帖子不存在', HttpStatus.NOT_FOUND);
    return item;
  }

  @Put('posts/:id/status')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updatePostStatus(@Param('id', ParseIntPipe) id: number, @Body() body: { status: string }) {
    const item = await this.prisma.post.update({ where: { id }, data: { status: body.status } });
    return item;
  }

  @Delete('posts/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async deletePost(@Param('id', ParseIntPipe) id: number) {
    await this.prisma.post.delete({ where: { id } });
    return { ok: true };
  }

  // --- AI Tools Admin ---
  @Get('tools')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminTools(@Query('page') page?: string, @Query('pageSize') pageSize?: string, @Query('search') search?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const where: any = {};
    if (search) where.name = { contains: search };
    const [items, total] = await Promise.all([
      this.prisma.tool.findMany({ where, orderBy: { createdAt: 'desc' }, skip: (p - 1) * ps, take: ps }),
      this.prisma.tool.count({ where }),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Get('tools/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminTool(@Param('id', ParseIntPipe) id: number) {
    const item = await this.prisma.tool.findUnique({ where: { id } });
    if (!item) throw new HttpException('工具不存在', HttpStatus.NOT_FOUND);
    return item;
  }

  @Post('tools')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async createTool(@Body() body: any) {
    const item = await this.prisma.tool.create({ data: body });
    return item;
  }

  @Put('tools/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updateTool(@Param('id', ParseIntPipe) id: number, @Body() body: any) {
    const { id: _id, ...data } = body;
    const item = await this.prisma.tool.update({ where: { id }, data });
    return item;
  }

  @Delete('tools/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async deleteTool(@Param('id', ParseIntPipe) id: number) {
    await this.prisma.tool.delete({ where: { id } });
    return { ok: true };
  }

  // --- AI Models Admin ---
  @Get('models')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminModels(@Query('page') page?: string, @Query('pageSize') pageSize?: string) {
    const p = Math.max(1, Number(page) || 1);
    const ps = Math.min(100, Math.max(1, Number(pageSize) || 20));
    const [items, total] = await Promise.all([
      this.prisma.aiModel.findMany({ orderBy: { sortOrder: 'asc' }, skip: (p - 1) * ps, take: ps }),
      this.prisma.aiModel.count(),
    ]);
    return { items, total, page: p, pageSize: ps };
  }

  @Get('models/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async adminModel(@Param('id', ParseIntPipe) id: number) {
    const item = await this.prisma.aiModel.findUnique({ where: { id } });
    if (!item) throw new HttpException('模型不存在', HttpStatus.NOT_FOUND);
    return item;
  }

  @Post('models')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async createModel(@Body() body: any) {
    const item = await this.prisma.aiModel.create({ data: body });
    return item;
  }

  @Put('models/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async updateModel(@Param('id', ParseIntPipe) id: number, @Body() body: any) {
    const { id: _id, ...data } = body;
    const item = await this.prisma.aiModel.update({ where: { id }, data });
    return item;
  }

  @Delete('models/:id')
  @UseGuards(AuthGuard('jwt'), AdminGuard)
  @ApiBearerAuth()
  async deleteModel(@Param('id', ParseIntPipe) id: number) {
    await this.prisma.aiModel.delete({ where: { id } });
    return { ok: true };
  }
}
