import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CylinderMovement, CylinderStatus } from '@prisma/client';

@Injectable()
export class ExternalApiService {

  constructor(private readonly prisma: PrismaService) { }

  async pushapi(data: {
    reader_name: string;
    event_data: { ep: string; at: number }[];
    event_type: string;
  }) {
    console.log("push/rfid call successfully", data);
    const { reader_name, event_data, event_type } = data;

    if (event_type !== "tag_read") {
      console.log("Event type is not READ, ignoring.");
      return { message: "Event type is not READ, ignoring." };
    }

    if (!reader_name || !event_data?.length) {
      console.log("Invalid payload");
      return { message: "Invalid payload" };
    }

    const reader = await this.prisma.reader.findUnique({
      where: { reader_id: reader_name },
    });

    if (!reader) {
      throw new Error(`Reader with ID ${reader_name} not found.`);
    }

    await this.prisma.reader.update({
      where: { id: reader.id },
      data: { lastSeen: new Date() },
    });

    const rfids = event_data.map((d) => d.ep);

    const cylindersToUpdate = await this.prisma.cylinders.findMany({
      where: { rfid: { in: rfids } },
      select: { id: true },
    });

    const cylinderIds = cylindersToUpdate.map((c) => c.id);





    if (reader.type === 'INSIDE') {

      const warehouse = await this.prisma.warehouse.findFirst({
        where: { readerId: reader.id },
      });

      if (!warehouse) {
        throw new Error(`Warehouse not found for reader ID ${reader_name}`);
      }


      for (const cylinderId of cylinderIds) {

        const cylinder = await this.prisma.cylinders.findUnique({
          where: { id: cylinderId },
        });
        if (!cylinder) {
          throw new Error(`Cylinder with ID ${cylinderId} not found.`);
        }

        await this.prisma.cylinders.update({
          where: { id: cylinderId },
          data: { warehouseId: warehouse.id, status: CylinderStatus.INSIDE },
        });

        const cylinderLog = await this.prisma.cylinder_logs.findFirst({
          where: { cylinderId: cylinderId },
          orderBy: { createdAt: "desc" },
        })

        if (!cylinderLog || !(cylinderLog.movement === CylinderMovement.INSIDE && cylinderLog.warehouse === warehouse.name)) {
          await this.prisma.cylinder_logs.create({
            data: {
              cylinderId: cylinderId,
              movement: CylinderMovement.INSIDE,
              warehouse: warehouse.name,
              remark: `Cylinder assign to ${warehouse.name}`,
            },
          });
        }

      }

      return { message: `Cylinders assigned to warehouse successfully.` };

    } else if (reader.type === 'OUTSIDE') {

      for (const cylinderId of cylinderIds) {

        const cylinder = await this.prisma.cylinders.findUnique({
          where: { id: cylinderId },
        });
        if (!cylinder) {
          throw new Error(`Cylinder with ID ${cylinderId} not found.`);
        }

        const lastLog = await this.prisma.cylinder_logs.findFirst({
          where: { cylinderId },
          orderBy: { createdAt: "desc" },
        });

        if (lastLog && (lastLog.movement !== CylinderMovement.INSIDE || !lastLog.warehouse)) {
          throw new Error(`Cylinders is not inside warehouse.`);
        }

        // if (cylinder.status !== CylinderStatus.INSIDE) {
        //   // return { message: `Cylinders is not inside warehouse.` };
        //   throw new Error(`Cylinders is not inside warehouse.`);
        // }

        await this.prisma.cylinders.update({
          where: { id: cylinderId },
          data: { status: CylinderStatus.OUTSIDE },
        });

        const cylinderLog = await this.prisma.cylinder_logs.findFirst({
          where: { cylinderId: cylinderId },
          orderBy: { createdAt: "desc" },
        })

        if (!cylinderLog || cylinderLog.movement !== CylinderMovement.OUTSIDE) {
          await this.prisma.cylinder_logs.create({
            data: {
              cylinderId,
              movement: CylinderMovement.OUTSIDE,
              remark: 'Cylinder is out for delivery',
            },
          });
        }

      }


      return { message: `Cylinders removed from warehouse.` };
    } else {
      throw new Error(`Unknown reader type: ${reader.type}`);
    }




  }
}
