import { Controller, Get, Post, Param, UseGuards, Patch, Query, Body } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiHeader, ApiBody } from '@nestjs/swagger';
import { OrdersService } from '../providers/orders.service';
import { AuthGuard } from '../../auth/guards/auth.guard';
import { UserId } from '../../../common/decorators/user-id.decorator';
import { RestId } from 'src/common/decorators/rest-id.decorator';
import { AdminAuthGuard } from '../../auth/guards/adminAuth.guard';
import { FindOrdersDto } from '../dto/find-orders.dto';
import { OrderStatus } from '../interface/order.interface';
import { API_HEADER_SLUG } from 'src/common/constants/index';
import { UpdateOrderStatusDto } from '../dto/update-order-status.dto';
import { Permissions } from 'src/common/decorators/permissions.decorator';
import { Permission } from 'src/common/enums/permission.enum';
import { AdminCreateOrderDto } from '../dto/admin-create-order.dto';

@ApiTags('orders')
@ApiBearerAuth()
@Controller()
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) { }

  @UseGuards(AuthGuard)
  @Post('public/checkout')
  @ApiHeader(API_HEADER_SLUG)
  @ApiOperation({ summary: 'Checkout : create order and payment record' })
  checkout(@UserId() userId: string, @RestId() restaurantId: string) {
    return this.ordersService.checkout(userId, restaurantId);
  }

  @UseGuards(AuthGuard)
  @Get('public/orders')
  @ApiHeader(API_HEADER_SLUG)
  @ApiOperation({ summary: 'Get all orders with pagination and filters' })
  findAll(@RestId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) {
    return this.ordersService.findAllForUser(restId, dto, userId);
  }

  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Get an order By id for User' })
  @ApiParam({ name: 'orderId', description: 'Order ID' })
  @ApiHeader(API_HEADER_SLUG)
  @Get('public/orders/:orderId')
  findOne(@Param('orderId') orderId: string, @RestId() restId: string) {
    return this.ordersService.findOne(orderId, restId);
  }

  @UseGuards(AuthGuard)
  @Patch('public/orders/:id/:status')
  @ApiParam({
    name: 'status',
    description: 'Order status',
    enum: OrderStatus,
  })
  @ApiHeader(API_HEADER_SLUG)
  @ApiBody({ type: UpdateOrderStatusDto })
  @ApiOperation({ summary: 'Update status of an order By User' })
  @ApiParam({ name: 'id', description: 'Order ID' })
  cancelOrder(
    @Body() dto: UpdateOrderStatusDto,
    @Param('id') orderId: string,
    @Param('status') status: OrderStatus,
    @RestId() restId: string,
  ) {
    return this.ordersService.changeOrderStatus(orderId, restId, status, 'user', dto?.desc);
  }

  /********************  Admin Routes **********************/
  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.MANAGE_ORDERS)
  @Post('admin/orders')
  @ApiOperation({ summary: 'Create an order for a user (by phone) from admin side' })
  @ApiBody({ type: AdminCreateOrderDto })
  createOrderForUser(@RestId() restId: string, @Body() dto: AdminCreateOrderDto) {
    return this.ordersService.createOrderForUserByPhone(restId, dto);
  }

  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.MANAGE_ORDERS)
  @Get('admin/orders')
  @ApiOperation({ summary: 'Get all orders with pagination and filters' })
  findAllAdmin(@RestId() restId: string, @Query() dto: FindOrdersDto) {
    return this.ordersService.findAllForAdmin(restId, dto);
  }

  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.MANAGE_ORDERS)
  @ApiOperation({ summary: 'Get an order By id for User' })
  @ApiParam({ name: 'orderId', description: 'Order ID' })
  @Get('admin/orders/:orderId')
  findOneAsAdmin(@Param('orderId') orderId: string, @RestId() restId: string) {
    return this.ordersService.findOne(orderId, restId);
  }

  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.MANAGE_ORDERS)
  @Patch('admin/orders/:orderId/:status')
  @ApiOperation({ summary: 'Update an order status' })
  @ApiParam({ name: 'orderId', description: 'Order ID' })
  @ApiBody({ type: UpdateOrderStatusDto })
  @ApiParam({
    name: 'status',
    description: 'Order status',
    enum: OrderStatus,
  })
  updateStatus(
    @Param('orderId') orderId: string,
    @Body() dto: UpdateOrderStatusDto,
    @Param('status') status: OrderStatus,
    @RestId() restId: string,
  ) {
    return this.ordersService.changeOrderStatus(orderId, restId, status, 'admin', dto?.desc);
  }

  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.VIEW_REPORTS)
  @ApiOperation({ summary: 'Get Stats for report page' })
  @Get('admin/orders/stats')
  findStats(@RestId() restId: string) {
    return this.ordersService.getStats(restId);
  }

  @UseGuards(AdminAuthGuard)
  @Permissions(Permission.VIEW_REPORTS)
  @ApiOperation({ summary: 'Get food sales pie chart data for last month' })
  @ApiHeader(API_HEADER_SLUG)
  @Get('admin/orders/food-sales-pie-chart')
  getFoodSalesPieChart(@RestId() restId: string) {
    return this.ordersService.getFoodSalesPieChart(restId);
  }
}
