import {
    BadRequestException,
    ConflictException,
    Injectable,
    InternalServerErrorException,
    NotFoundException,
} from "@nestjs/common";
import { PrismaService } from "../../prisma/prisma.service";

import { handlePrismaError } from "src/common/lib/handlePrismaError";
import { ConfigService } from "@nestjs/config";
import {
    formatNoDataResponse,
    formatPaginatedResponse,
    getPaginationOptions,
} from "src/common/lib/pagination-helper";
import { maintenance_history } from "@prisma/client";

@Injectable()
export class MaintenanceHistoryService {
    constructor(
        private prisma: PrismaService,
        private readonly configService: ConfigService,
    ) { }

    async create(body: any) {
        try {
            const maintenanceHistory = await this.prisma.maintenance_history.create({
                data: body,
            });
            return maintenanceHistory;
        } catch (error) {
            handlePrismaError(error, "Error creating maintenance history");
        }
    }

    async findAll(page: number, perPage: number, workType?: string, query?: string, dateFrom?: string, dateTo?: string, warehouseId?: string, user?: any,) {
        try {
            const { skip, take } = getPaginationOptions({ page, perPage });

            const where: any = {};

            // Filter by workType if provided
            if (workType) {
                where.workType = workType;
            }

            // Filter by search query (RFID, workType, or createdByName)
            if (query) {
                where.OR = [
                    // { workType: { contains: query } },
                    // { createdByName: { contains: query } },
                    { cylinder: { is: { rfid: { contains: query } } } },
                    { cylinder: { is: { item_id: { contains: query } } } },
                ];
            }
            // Filter by date range
            if (dateFrom || dateTo) {
                where.AND = [];

                if (dateFrom) {
                    where.AND.push({
                        date: { gte: new Date(dateFrom) },
                    });
                }

                if (dateTo) {
                    // Add one day to include the entire end date
                    const endDate = new Date(dateTo);
                    endDate.setDate(endDate.getDate() + 1);
                    where.AND.push({
                        date: { lt: endDate },
                    });
                }
            }

            if (warehouseId && warehouseId.trim() !== '') {
                where.cylinder = {
                    warehouseId: warehouseId,
                };
            } else if (user && user.role !== 'ADMIN') {
                const getUser = await this.prisma.users.findFirst({
                    where: {
                        id: user.sub
                    }
                })
                where.cylinder = {
                    warehouseId: getUser?.warehouseId
                };

            }

            const [items, total] = await this.prisma.$transaction([
                this.prisma.maintenance_history.findMany({
                    where,
                    include: {
                        cylinder: {
                            select: {
                                rfid: true,
                                item_id: true,
                            },
                        },
                    },
                    skip,
                    take,
                    orderBy: { createdAt: "desc" },
                }),
                this.prisma.maintenance_history.count({ where }),
            ]);

            return formatPaginatedResponse(items, total, page, perPage);
        } catch (error) {
            handlePrismaError(error, "Fetching paginated Maintenance History");
        }
    }

    async search(query: string, page: number, perPage: number) {
        const cleanedQuery = query?.trim();
        if (!cleanedQuery) throw new BadRequestException("Search query is required");

        const { skip, take } = getPaginationOptions({ page, perPage });

        const where = {
            OR: [
                { workType: { contains: cleanedQuery } },
                { createdByName: { contains: cleanedQuery } },
                { cylinder: { is: { rfid: { contains: cleanedQuery } } } },
                { cylinder: { is: { item_id: { contains: cleanedQuery } } } },
            ],
        };

        const [items, total] = await this.prisma.$transaction([
            this.prisma.maintenance_history.findMany({
                where,
                include: {
                    cylinder: {
                        select: {
                            rfid: true,
                        },
                    },
                },
                skip,
                take,
                orderBy: { createdAt: "desc" },
            }),
            this.prisma.maintenance_history.count({ where }),
        ]);

        if (total === 0) return formatNoDataResponse("Maintenance History Not Found.");
        return formatPaginatedResponse(items, total, page, perPage);
    }

    async findAllByCylinder(cylinderId: string, page: number, perPage: number) {
        try {
            const { skip, take } = getPaginationOptions({ page, perPage });

            const [items, total] = await this.prisma.$transaction([
                this.prisma.maintenance_history.findMany({
                    where: { cylinderId },
                    skip,
                    take,
                    orderBy: { createdAt: "desc" },
                }),
                this.prisma.maintenance_history.count({ where: { cylinderId } }),
            ]);

            return formatPaginatedResponse(items, total, page, perPage);
        } catch (error) {
            handlePrismaError(error, "Fetching paginated Maintenance History");
        }
    }

}
