import {
  BadRequestException,
  ConflictException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateDriverDto } from './dto/create-driver.dto';
import { UpdateDriverDto } from './dto/update-driver.dto';
import { getPaginationOptions, formatPaginatedResponse } from 'src/common/lib/pagination-helper';
import { handlePrismaError } from 'src/common/lib/handlePrismaError';
import { get } from 'axios';

@Injectable()
export class DriverService {
  constructor(private prisma: PrismaService) { }

  async create(createDriverDto: CreateDriverDto, user?: any) {
    try {
      let warehouseId = createDriverDto.warehouseId;

      if (user.role !== 'ADMIN') {
        const getUser = await this.prisma.users.findUnique({
          where: { id: user.sub },
          select: { warehouseId: true },
        });

        if (!getUser?.warehouseId) {
          throw new NotFoundException('User warehouse not found');
        }

        warehouseId = getUser.warehouseId;
      }

      if (!warehouseId) {
        throw new BadRequestException('WarehouseId is required');
      }

      return await this.prisma.driver.create({
        data: {
          ...createDriverDto,
          warehouseId,
        },
      });
    } catch (error) {
      handlePrismaError(error, 'Error creating driver');
    }
  }


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

    const where: any = {};

    if (query) {
      where.OR = [
        { name: { contains: query } },
        { contactNumber: { contains: query } },
        { drivingLicense: { contains: query } },
      ];
    }

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

    const [items, total] = await this.prisma.$transaction([
      this.prisma.driver.findMany({
        where,
        skip,
        take,
        include: {
          warehouse: {
            select: {
              name: true
            }
          }
        }
      }),
      this.prisma.driver.count({ where }),
    ]);

    return formatPaginatedResponse(items, total, page, perPage);
  }

  async findOne(id: string) {
    const driver = await this.prisma.driver.findUnique({
      where: { id },
      include: {
        warehouse: {
          select: {
            name: true
          }
        }
      }
    });

    if (!driver) {
      throw new NotFoundException(`Driver with ID ${id} not found`);
    }

    return driver;
  }

  async update(id: string, updateDriverDto: UpdateDriverDto, user?: any) {
    await this.findOne(id);

    try {
      let warehouseId = updateDriverDto.warehouseId;

      if (user?.role !== 'ADMIN') {
        const getUser = await this.prisma.users.findUnique({
          where: { id: user.sub },
          select: { warehouseId: true },
        });

        if (!getUser?.warehouseId) {
          throw new NotFoundException('User warehouse not found');
        }

        warehouseId = getUser.warehouseId;
      }

      return await this.prisma.driver.update({
        where: { id },
        data: {
          ...updateDriverDto,
          warehouseId,
        },
      });
    } catch (error) {
      handlePrismaError(error, 'Error updating driver');
    }
  }


  async remove(id: string) {
    await this.findOne(id);
    return this.prisma.driver.delete({
      where: { id },
    });
  }
}
