import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CurrentUser, JwtAuthGuard, type JwtPayload } from '@modules/auth';
import { NotFoundException } from '@modules/shared';
import { CreateIndustrialListingCommand } from '../../application/commands/create-industrial-listing/create-industrial-listing.command';
import { DeleteIndustrialListingCommand } from '../../application/commands/delete-industrial-listing/delete-industrial-listing.command';
import { UpdateIndustrialListingCommand } from '../../application/commands/update-industrial-listing/update-industrial-listing.command';
import { GetIndustrialListingQuery } from '../../application/queries/get-industrial-listing/get-industrial-listing.query';
import { ListIndustrialListingsQuery } from '../../application/queries/list-industrial-listings/list-industrial-listings.query';
import { CreateIndustrialListingDto } from '../dto/create-industrial-listing.dto';
import { SearchIndustrialListingsDto } from '../dto/search-industrial-listings.dto';
import { UpdateIndustrialListingDto } from '../dto/update-industrial-listing.dto';

@ApiTags('industrial-listings')
@Controller('industrial')
export class IndustrialListingsController {
  constructor(
    private readonly commandBus: CommandBus,
    private readonly queryBus: QueryBus,
  ) {}

  // ── Public endpoints ──────────────────────────────────────────────

  @ApiOperation({ summary: 'Danh sách BĐS công nghiệp', description: 'Tìm kiếm và lọc tin đăng BĐS công nghiệp' })
  @ApiResponse({ status: 200, description: 'Danh sách tin đăng phân trang' })
  @Get('listings')
  async listListings(@Query() dto: SearchIndustrialListingsDto) {
    return this.queryBus.execute(
      new ListIndustrialListingsQuery(
        dto.parkId,
        dto.propertyType,
        dto.leaseType,
        dto.status,
        dto.minAreaM2,
        dto.maxAreaM2,
        dto.minPriceUsdM2,
        dto.maxPriceUsdM2,
        dto.q,
        dto.page ?? 1,
        dto.limit ?? 20,
      ),
    );
  }

  @ApiOperation({ summary: 'Chi tiết tin đăng', description: 'Xem chi tiết tin đăng BĐS công nghiệp' })
  @ApiResponse({ status: 200, description: 'Thông tin chi tiết tin đăng' })
  @ApiResponse({ status: 404, description: 'Không tìm thấy tin đăng' })
  @Get('listings/:id')
  async getListing(@Param('id') id: string) {
    const result = await this.queryBus.execute(new GetIndustrialListingQuery(id));
    if (!result) {
      throw new NotFoundException('Industrial listing', id);
    }
    return result;
  }

  // ── Authenticated endpoints ───────────────────────────────────────

  @ApiOperation({ summary: 'Tạo tin đăng', description: 'Tạo mới tin đăng BĐS công nghiệp' })
  @ApiResponse({ status: 201, description: 'Tin đăng đã tạo' })
  @ApiResponse({ status: 400, description: 'Validation error' })
  @ApiResponse({ status: 401, description: 'Chưa xác thực' })
  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard)
  @Post('listings')
  async createListing(@Body() dto: CreateIndustrialListingDto, @CurrentUser() user: JwtPayload) {
    return this.commandBus.execute(
      new CreateIndustrialListingCommand(
        dto.parkId,
        user.sub,
        dto.agentId ?? null,
        dto.propertyType,
        dto.leaseType,
        dto.title,
        dto.description ?? null,
        dto.areaM2,
        dto.ceilingHeightM ?? null,
        dto.floorLoadTonM2 ?? null,
        dto.columnSpacingM ?? null,
        dto.dockCount ?? null,
        dto.craneCapacityTon ?? null,
        dto.hasMezzanine ?? false,
        dto.hasOfficeArea ?? false,
        dto.officeAreaM2 ?? null,
        dto.priceUsdM2 ?? null,
        dto.pricingUnit ?? null,
        dto.totalLeasePrice ?? null,
        dto.managementFee ?? null,
        dto.depositMonths ?? null,
        dto.minLeaseYears ?? null,
        dto.maxLeaseYears ?? null,
        dto.leaseExpiry ? new Date(dto.leaseExpiry) : null,
        dto.availableFrom ? new Date(dto.availableFrom) : null,
        dto.powerCapacityKva ?? null,
        dto.waterSupplyM3Day ?? null,
        dto.media ?? null,
      ),
    );
  }

  @ApiOperation({ summary: 'Cập nhật tin đăng', description: 'Cập nhật thông tin tin đăng BĐS công nghiệp' })
  @ApiResponse({ status: 200, description: 'Tin đăng đã cập nhật' })
  @ApiResponse({ status: 401, description: 'Chưa xác thực' })
  @ApiResponse({ status: 404, description: 'Không tìm thấy tài nguyên' })
  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard)
  @Patch('listings/:id')
  async updateListing(@Param('id') id: string, @Body() dto: UpdateIndustrialListingDto) {
    return this.commandBus.execute(
      new UpdateIndustrialListingCommand(
        id,
        dto.propertyType,
        dto.leaseType,
        dto.status,
        dto.title,
        dto.description,
        dto.areaM2,
        dto.ceilingHeightM,
        dto.floorLoadTonM2,
        dto.columnSpacingM,
        dto.dockCount,
        dto.craneCapacityTon,
        dto.hasMezzanine,
        dto.hasOfficeArea,
        dto.officeAreaM2,
        dto.priceUsdM2,
        dto.pricingUnit,
        dto.totalLeasePrice,
        dto.managementFee,
        dto.depositMonths,
        dto.minLeaseYears,
        dto.maxLeaseYears,
        dto.leaseExpiry ? new Date(dto.leaseExpiry) : dto.leaseExpiry as undefined,
        dto.availableFrom ? new Date(dto.availableFrom) : dto.availableFrom as undefined,
        dto.powerCapacityKva,
        dto.waterSupplyM3Day,
        dto.media,
      ),
    );
  }

  @ApiOperation({ summary: 'Xóa tin đăng', description: 'Xóa mềm tin đăng BĐS công nghiệp' })
  @ApiResponse({ status: 200, description: 'Tin đăng đã xóa' })
  @ApiResponse({ status: 401, description: 'Chưa xác thực' })
  @ApiResponse({ status: 404, description: 'Không tìm thấy tài nguyên' })
  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard)
  @Delete('listings/:id')
  async deleteListing(@Param('id') id: string) {
    return this.commandBus.execute(new DeleteIndustrialListingCommand(id));
  }
}
