"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var SalesController_1;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SalesController = void 0;
const common_1 = require("@nestjs/common");
const swagger_1 = require("@nestjs/swagger");
const sales_service_1 = require("./sales.service");
const create_sale_dto_1 = require("./dto/create-sale.dto");
const sale_response_dto_1 = require("./dto/sale-response.dto");
const jwt_auth_guard_1 = require("../auth/guards/jwt-auth.guard");
const tenant_guard_1 = require("../auth/guards/tenant.guard");
const current_user_decorator_1 = require("../auth/decorators/current-user.decorator");
const client_1 = require("@prisma/client");
let SalesController = SalesController_1 = class SalesController {
    constructor(salesService) {
        this.salesService = salesService;
        this.logger = new common_1.Logger(SalesController_1.name);
    }
    async create(createSaleDto, user) {
        this.logger.log(`Creating sale for user ${user.id} in tenant ${user.tenantId}`);
        const sale = await this.salesService.createSale(createSaleDto, user);
        this.logger.log(`Sale created: ${sale.saleNumber}`);
        return sale;
    }
    async findAll(page, limit, status, startDateStr, endDateStr, user) {
        this.logger.log(`Fetching sales for tenant ${user.tenantId}, page ${page}, limit ${limit}`);
        let startDate;
        let endDate;
        if (startDateStr) {
            startDate = new Date(startDateStr);
            if (isNaN(startDate.getTime())) {
                throw new Error('Invalid startDate format');
            }
        }
        if (endDateStr) {
            endDate = new Date(endDateStr);
            if (isNaN(endDate.getTime())) {
                throw new Error('Invalid endDate format');
            }
        }
        if (page < 1)
            page = 1;
        if (limit < 1)
            limit = 20;
        if (limit > 100)
            limit = 100;
        const { sales, total } = await this.salesService.findAll(user, page, limit, status, startDate, endDate);
        const totalPages = Math.ceil(total / limit);
        return {
            sales,
            total,
            page,
            limit,
            totalPages,
        };
    }
    async getSummary(user) {
        this.logger.log(`Fetching sales summary for tenant ${user.tenantId}`);
        const today = new Date();
        const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
        const { sales: allSales } = await this.salesService.findAll(user, 1, 1000);
        const { sales: todaySales } = await this.salesService.findAll(user, 1, 1000, undefined, startOfDay);
        const totalRevenue = allSales.reduce((sum, sale) => sum + sale.total, 0);
        const todayRevenue = todaySales.reduce((sum, sale) => sum + sale.total, 0);
        const averageSaleAmount = allSales.length > 0 ? totalRevenue / allSales.length : 0;
        return {
            totalSales: allSales.length,
            totalRevenue,
            averageSaleAmount,
            todaySales: todaySales.length,
            todayRevenue,
        };
    }
    async findOne(id, user) {
        this.logger.log(`Fetching sale ${id} for tenant ${user.tenantId}`);
        return this.salesService.findOne(id, user);
    }
    async findBySaleNumber(saleNumber, user) {
        this.logger.log(`Fetching sale by number ${saleNumber} for tenant ${user.tenantId}`);
        throw new Error('Not implemented yet');
    }
    async getDailySales(dateStr, user) {
        this.logger.log(`Fetching daily sales for ${dateStr} in tenant ${user.tenantId}`);
        const date = new Date(dateStr);
        if (isNaN(date.getTime())) {
            throw new Error('Invalid date format. Use YYYY-MM-DD');
        }
        const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());
        const endOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
        return this.salesService.findAll(user, 1, 1000, undefined, startOfDay, endOfDay);
    }
};
exports.SalesController = SalesController;
__decorate([
    (0, common_1.Post)(),
    (0, swagger_1.ApiOperation)({
        summary: 'Create a new sale',
        description: 'Processes a new sale transaction with inventory management and audit trail',
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.CREATED,
        description: 'Sale created successfully',
        type: sale_response_dto_1.SaleResponseDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.BAD_REQUEST,
        description: 'Invalid input data or business rule violation',
        schema: {
            type: 'object',
            properties: {
                statusCode: { type: 'number', example: 400 },
                message: { type: 'string', example: 'Sale must contain at least one item' },
                error: { type: 'string', example: 'Bad Request' },
            },
        },
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.CONFLICT,
        description: 'Insufficient stock or other conflict',
        schema: {
            type: 'object',
            properties: {
                statusCode: { type: 'number', example: 409 },
                message: {
                    type: 'string',
                    example: 'Insufficient stock for product \"Coffee Beans\". Available: 5, Requested: 10'
                },
                error: { type: 'string', example: 'Conflict' },
            },
        },
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.NOT_FOUND,
        description: 'Product not found or inactive',
        schema: {
            type: 'object',
            properties: {
                statusCode: { type: 'number', example: 404 },
                message: {
                    type: 'string',
                    example: 'Products not found or inactive: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'
                },
                error: { type: 'string', example: 'Not Found' },
            },
        },
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.UNAUTHORIZED,
        description: 'Invalid or expired JWT token',
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.FORBIDDEN,
        description: 'User does not have access to this tenant',
    }),
    (0, common_1.UsePipes)(new common_1.ValidationPipe({
        transform: true,
        whitelist: true,
        forbidNonWhitelisted: true,
    })),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [create_sale_dto_1.CreateSaleDto, Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    (0, swagger_1.ApiOperation)({
        summary: 'Get all sales for the current tenant',
        description: 'Retrieves paginated list of sales with optional filtering',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'page',
        required: false,
        type: Number,
        description: 'Page number (1-based)',
        example: 1,
    }),
    (0, swagger_1.ApiQuery)({
        name: 'limit',
        required: false,
        type: Number,
        description: 'Number of items per page',
        example: 20,
    }),
    (0, swagger_1.ApiQuery)({
        name: 'status',
        required: false,
        enum: client_1.SaleStatus,
        description: 'Filter by sale status',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'startDate',
        required: false,
        type: String,
        description: 'Filter sales from this date (ISO string)',
        example: '2024-01-01T00:00:00.000Z',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'endDate',
        required: false,
        type: String,
        description: 'Filter sales until this date (ISO string)',
        example: '2024-12-31T23:59:59.999Z',
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.OK,
        description: 'List of sales retrieved successfully',
        schema: {
            type: 'object',
            properties: {
                sales: {
                    type: 'array',
                    items: { $ref: '#/components/schemas/SaleResponseDto' },
                },
                total: { type: 'number', example: 150 },
                page: { type: 'number', example: 1 },
                limit: { type: 'number', example: 20 },
                totalPages: { type: 'number', example: 8 },
            },
        },
    }),
    __param(0, (0, common_1.Query)('page', new common_1.DefaultValuePipe(1), common_1.ParseIntPipe)),
    __param(1, (0, common_1.Query)('limit', new common_1.DefaultValuePipe(20), common_1.ParseIntPipe)),
    __param(2, (0, common_1.Query)('status', new common_1.DefaultValuePipe(undefined))),
    __param(3, (0, common_1.Query)('startDate')),
    __param(4, (0, common_1.Query)('endDate')),
    __param(5, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Number, Number, typeof (_a = typeof client_1.SaleStatus !== "undefined" && client_1.SaleStatus) === "function" ? _a : Object, String, String, Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('summary'),
    (0, swagger_1.ApiOperation)({
        summary: 'Get sales summary for the current tenant',
        description: 'Retrieves key sales metrics and statistics',
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.OK,
        description: 'Sales summary retrieved successfully',
        type: sale_response_dto_1.SalesSummaryDto,
    }),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "getSummary", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, swagger_1.ApiOperation)({
        summary: 'Get a specific sale by ID',
        description: 'Retrieves detailed information about a specific sale',
    }),
    (0, swagger_1.ApiParam)({
        name: 'id',
        description: 'Sale ID',
        type: 'string',
        format: 'uuid',
        example: 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.OK,
        description: 'Sale retrieved successfully',
        type: sale_response_dto_1.SaleResponseDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: common_1.HttpStatus.NOT_FOUND,
        description: 'Sale not found',
        schema: {
            type: 'object',
            properties: {
                statusCode: { type: 'number', example: 404 },
                message: { type: 'string', example: 'Sale not found' },
                error: { type: 'string', example: 'Not Found' },
            },
        },
    }),
    __param(0, (0, common_1.Param)('id', new common_1.ParseUUIDPipe({ version: '4' }))),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Get)('by-number/:saleNumber'),
    (0, swagger_1.ApiOperation)({
        summary: 'Get a sale by sale number',
        description: 'Retrieves a sale using its human-readable sale number',
    }),
    (0, swagger_1.ApiParam)({
        name: 'saleNumber',
        description: 'Sale number (e.g., 20240115-0001)',
        type: 'string',
        example: '20240115-0001',
    }),
    __param(0, (0, common_1.Param)('saleNumber')),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "findBySaleNumber", null);
__decorate([
    (0, common_1.Get)('daily/:date'),
    (0, swagger_1.ApiOperation)({
        summary: 'Get sales for a specific date',
        description: 'Retrieves all sales for a specific date',
    }),
    (0, swagger_1.ApiParam)({
        name: 'date',
        description: 'Date in YYYY-MM-DD format',
        type: 'string',
        example: '2024-01-15',
    }),
    __param(0, (0, common_1.Param)('date')),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SalesController.prototype, "getDailySales", null);
exports.SalesController = SalesController = SalesController_1 = __decorate([
    (0, swagger_1.ApiTags)('Sales'),
    (0, swagger_1.ApiBearerAuth)(),
    (0, common_1.Controller)('sales'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, tenant_guard_1.TenantGuard),
    __metadata("design:paramtypes", [sales_service_1.SalesService])
], SalesController);
//# sourceMappingURL=sales.controller.js.map