"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 OrdersService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrdersService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const order_entity_1 = require("./entities/order.entity");
const product_entity_1 = require("../products/entities/product.entity");
const orderpiority_entity_1 = require("../orderpiorities/entities/orderpiority.entity");
const page_entity_1 = require("../pages/entities/page.entity");
const order_detail_entity_1 = require("../order_details/entities/order_detail.entity");
let OrdersService = OrdersService_1 = class OrdersService {
    constructor(orderRepository, productRepository, orderpiorityRepository, pageRepository, orderDetailRepository, connection) {
        this.orderRepository = orderRepository;
        this.productRepository = productRepository;
        this.orderpiorityRepository = orderpiorityRepository;
        this.pageRepository = pageRepository;
        this.orderDetailRepository = orderDetailRepository;
        this.connection = connection;
        this.logger = new common_1.Logger(OrdersService_1.name);
    }
    async create(createOrderDto) {
        this.logger.log(`Creating or updating order for customer ${createOrderDto.customerID}`);
        return await this.connection.transaction(async (manager) => {
            const isUpdate = !!createOrderDto.orderID;
            if (createOrderDto.orderDetails?.length > 0) {
                for (const detail of createOrderDto.orderDetails) {
                    const product = await this.productRepository.findOne({
                        where: { ProductID: detail.productID },
                    });
                    if (!product) {
                        throw new common_1.NotFoundException(`Product with ID ${detail.productID} not found`);
                    }
                    detail.Productname = `${product.brand} ${product.size}`;
                    detail.size = product.size;
                    detail.waterBrand = product.brand;
                    detail.status = detail.status || 'Active';
                    detail.totalPrice = detail.quantity * detail.pricePerUnit;
                }
            }
            if (!createOrderDto.status) {
                createOrderDto.status = 'กำลังรอ';
            }
            let order;
            if (isUpdate) {
                const existing = await this.orderRepository.findOne({
                    where: { OrderID: createOrderDto.orderID },
                    relations: ['orderDetails'],
                });
                if (!existing) {
                    throw new common_1.NotFoundException(`Order with ID ${createOrderDto.orderID} not found`);
                }
                Object.assign(existing, createOrderDto);
                if (createOrderDto.orderDetails) {
                    const orderDetailEntities = createOrderDto.orderDetails.map((dto) => this.orderDetailRepository.create(dto));
                    existing.orderDetails = orderDetailEntities;
                }
                order = await manager.save(existing);
                this.logger.log(`Order updated with ID ${order.OrderID}`);
            }
            else {
                order = this.orderRepository.create(createOrderDto);
                order = await manager.save(order);
                this.logger.log(`Order created with ID ${order.OrderID}`);
            }
            const allPages = await this.pageRepository.find({
                relations: ['orderPriorities'],
            });
            for (const page of allPages) {
                const alreadyExists = page.orderPriorities.some((op) => op.order?.OrderID === order.OrderID);
                if (!alreadyExists) {
                    const newPriority = this.orderpiorityRepository.create({
                        order,
                        page,
                        priority: page.orderPriorities.length + 1,
                    });
                    await manager.save(newPriority);
                    this.logger.log(`Created OrderPriority for Page ${page.PageID}`);
                }
            }
            return order;
        });
    }
    async upsertMany(ordersDto) {
        this.logger.log(`Upserting ${ordersDto.length} order(s)`);
        return await this.connection.transaction(async (manager) => {
            const upsertedOrders = [];
            const allPages = await this.pageRepository.find({
                relations: ['orderPriorities'],
            });
            for (const dto of ordersDto) {
                if (!dto.status) {
                    dto.status = 'กำลังรอ';
                }
                if (dto.orderDetails && dto.orderDetails.length > 0) {
                    for (const detail of dto.orderDetails) {
                        const product = await this.productRepository.findOne({
                            where: { ProductID: detail.productID },
                        });
                        if (!product) {
                            throw new common_1.NotFoundException(`Product with ID ${detail.productID} not found`);
                        }
                        detail.Productname = `${product.brand} ${product.size}`;
                        detail.size = product.size;
                        detail.waterBrand = product.brand;
                        detail.status = detail.status || 'Active';
                        detail.totalPrice = detail.quantity * detail.pricePerUnit;
                    }
                }
                const orderEntity = this.orderRepository.create(dto);
                const savedOrder = await manager.save(orderEntity);
                upsertedOrders.push(savedOrder);
                this.logger.log(`📝 Order upserted with ID ${savedOrder.OrderID}`);
                for (const page of allPages) {
                    const alreadyExists = page.orderPriorities?.some((op) => op.order?.OrderID === savedOrder.OrderID);
                    if (!alreadyExists) {
                        const newPriority = this.orderpiorityRepository.create({
                            order: savedOrder,
                            page: page,
                            priority: page.orderPriorities.length + 1,
                        });
                        const savedPriority = await manager.save(newPriority);
                        page.orderPriorities.push(savedPriority);
                        this.logger.log(`📌 OrderPriority created in Page ${page.PageID} for Order ${savedOrder.OrderID}`);
                    }
                }
            }
            return upsertedOrders;
        });
    }
    async findAll() {
        this.logger.log('Fetching all orders with orderDetails');
        const orders = await this.orderRepository.find({
            relations: ['orderDetails'],
        });
        this.logger.log(`Fetched ${orders.length} order(s)`);
        return orders;
    }
    async findOne(id) {
        this.logger.log(`Fetching order with ID ${id}`);
        const order = await this.orderRepository.findOne({
            where: { OrderID: id },
            relations: ['orderDetails'],
        });
        if (!order) {
            this.logger.error(`Order with ID ${id} not found`);
            throw new common_1.NotFoundException(`Order with ID ${id} not found`);
        }
        this.logger.log(`Order with ID ${id} fetched successfully`);
        return order;
    }
    async update(id, updateOrderDto) {
        this.logger.log(`Updating order with ID ${id}`);
        await this.orderRepository.update(id, updateOrderDto);
        const updatedOrder = await this.findOne(id);
        this.logger.log(`Order with ID ${id} updated successfully`);
        return updatedOrder;
    }
    async remove(id) {
        this.logger.log(`Deleting order with ID ${id}`);
        const order = await this.orderRepository.findOne({
            where: { OrderID: id },
            relations: ['orderDetails'],
        });
        if (!order) {
            this.logger.error(`Order with ID ${id} not found for deletion`);
            throw new common_1.NotFoundException(`Order with ID ${id} not found`);
        }
        if (order.orderDetails && order.orderDetails.length > 0) {
            this.logger.log(`Deleting ${order.orderDetails.length} orderDetails for order ID ${id}`);
            await this.orderDetailRepository.remove(order.orderDetails);
        }
        await this.orderRepository.remove(order);
        this.logger.log(`Order with ID ${id} and its orderDetails deleted`);
        return order;
    }
};
exports.OrdersService = OrdersService;
exports.OrdersService = OrdersService = OrdersService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(order_entity_1.Order)),
    __param(1, (0, typeorm_1.InjectRepository)(product_entity_1.Product)),
    __param(2, (0, typeorm_1.InjectRepository)(orderpiority_entity_1.OrderPriority)),
    __param(3, (0, typeorm_1.InjectRepository)(page_entity_1.Page)),
    __param(4, (0, typeorm_1.InjectRepository)(order_detail_entity_1.OrderDetail)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Connection])
], OrdersService);
//# sourceMappingURL=orders.service.js.map