import {
    Controller,
    Get,
    HttpStatus,
    Param,
    ParseUUIDPipe,
    Query,
    Res,
} from "@nestjs/common";
import {
    ApiTags,
    ApiOperation,
    ApiQuery,
    ApiOkResponse,
    ApiProduces,
} from "@nestjs/swagger";
import { Response } from "express";
import { Public } from "@edr/api-common";
import { BookingStaff, BookingView } from "../../common/booking-guards";
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
import { PaymentService } from "./payment.service";
import { IntentStatusDto } from "./payments.dto";

@ApiTags("Payment")
@Controller("payments")
export class PaymentController {
    constructor(private readonly paymentService: PaymentService) { }

    // Customer-detail payments tab — same one-of rule as the bookings tab.
    @Get("by-company/:companyId/customer-view")
    @BookingStaff([FREIGHT_PERMS.customers.view, FREIGHT_PERMS.payments.view])
    @ApiOperation({ summary: "List payments for a company (customer-view shape, backoffice)" })
    findByCompanyCustomerView(
        @Param("companyId", ParseUUIDPipe) companyId: string,
    ) {
        return this.paymentService.findByCompanyId(companyId);
    }

    @Get("summary")
    @BookingView()
    @ApiOperation({ summary: "Payment count/amount summary for dashboard cards" })
    getSummary() {
        return this.paymentService.getSummary();
    }

    @Get("all")
    @BookingView()
    @ApiOperation({ summary: "Get all payments with filters (view-only, any staff)" })
    @ApiQuery({ name: "search", required: false })
    @ApiQuery({ name: "status", required: false })
    @ApiQuery({ name: "method", required: false })
    @ApiQuery({ name: "page", required: false })
    @ApiQuery({ name: "pageSize", required: false })
    async getAll(
        @Query("search") search?: string,
        @Query("status") status?: string,
        @Query("method") method?: string,
        @Query("page") page?: string,
        @Query("pageSize") pageSize?: string,
    ) {
        return this.paymentService.getAll({
            search,
            status,
            method,
            page: page ? parseInt(page) : 1,
            pageSize: pageSize ? parseInt(pageSize) : 10,
        });
    }

    @Get("intents/:bookingId")
    @ApiOperation({ summary: "Get payment intent status for a booking" })
    @ApiOkResponse({ type: IntentStatusDto })
    getIntent(@Param("bookingId") bookingId: string) {
        return this.paymentService.getIntentByBookingId(bookingId);
    }

    @Get("receipt/:orderId")
    @Public()
    @ApiOperation({ summary: "Generate a payment receipt HTML page" })
    @ApiProduces("text/html")
    async receipt(@Param("orderId") orderId: string, @Res() res: Response) {
        const html = await this.paymentService.genReceiptHtml(orderId);
        return res.status(HttpStatus.OK).type("html").send(html);
    }
}
