import { Controller, Get, Logger, Query } from '@nestjs/common';
import { PrismaService } from './core/database/prisma.service';
import { AnomaliesService } from './modules/feat-anomalies/anomalies.service';
import { CalculationService } from './modules/feat-calculation/calculation.service';
import { ImporterService } from './modules/feat-etl/feat-importers/importer.service';
import { TicketService } from './modules/feat-tickets/tickets.service';

@Controller()
export class AppController {
  private logger = new Logger(AppController.name);

  constructor(
    private readonly importer: ImporterService,
    private readonly anomaliesService: AnomaliesService,
    private readonly ticketService: TicketService,
    private readonly calculationService: CalculationService,
    private readonly prisma: PrismaService,
  ) {}

  @Get('etl')
  etl(@Query('from') from: string, @Query('to') to: string) {
    this.logger.log(`Start ETL for interval from=${from} to=${to}`);

    if (!from || !to) {
      return {
        error: 'from and to must be defined',
      };
    }
    const interval = {
      start: new Date(from),
      end: new Date(to),
    };
    return this.importer.runImportForRange(interval);
  }

  @Get('tickets')
  tickets(@Query('from') from: string, @Query('to') to: string) {
    if (!from || !to) {
      return {
        error: 'from and to must be defined',
      };
    }
    const interval = {
      start: new Date(from),
      end: new Date(to),
    };
    return this.ticketService.createTickets(interval);
  }

  @Get('anomalies')
  anomalies(@Query('from') from: string, @Query('to') to: string) {
    if (!from || !to) {
      return {
        error: 'from and to must be defined',
      };
    }
    const interval = {
      start: new Date(from),
      end: new Date(to),
    };
    return this.anomaliesService
      .detectAnomalies(interval)
      .then(() => this.anomaliesService.validateAnomalies());
  }

  @Get('updated-tours')
  async updatedTours(@Query('from') from: string, @Query('to') to: string) {
    const interval = {
      start: new Date(from),
      end: new Date(to),
    };
    return await this.importer.runTourUpdateCheck(interval);
  }

  @Get('schichtplanung')
  async syncSchichtplanung(@Query('day') day: string) {
    return await this.importer.runSchichtplanungSync(new Date(day));
  }

  //! Used to create check 2 report
  @Get('tour-calculation')
  async tourCalculation(@Query('from') from: string, @Query('to') to: string) {
    const interval = {
      start: new Date(from),
      end: new Date(to),
    };
    const tours = await this.prisma.tour.findMany({
      where: {
        AND: [
          {
            startDate: {
              gte: new Date(interval.start),
            },
          },
          {
            startDate: {
              lt: new Date(interval.end),
            },
          },
          {
            healthInsurance: {
              not: 'KOSTENTRÄGER PATIENT',
            },
          },
          {
            OR: [
              {
                carName: null,
              },
              {
                AND: [
                  {
                    carName: {
                      not: 'Storno',
                    },
                  },
                  {
                    carName: {
                      not: 'Löschen',
                    },
                  },
                  {
                    carName: {
                      not: 'Abgabe',
                    },
                  },
                ],
              },
            ],
          },
          {
            check: 2,
          },
          {
            deletedAt: null,
          },
          {
            OR: [
              {
                patientId: null,
              },
              {
                patientId: {
                  // Pause
                  not: 'b7424477-a4b2-42f7-b7e7-a4bef24f6979',
                },
              },
              {
                patientId: {
                  // Feierabend
                  not: '3554e1a9-9c07-45e5-b53c-692a77e4fa9a',
                },
              },
            ],
          },
        ],
      },
    });
    const toursWithRevenue = [];
    for (const tour of tours) {
      toursWithRevenue.push({
        ...tour,
        revenue: await this.calculationService.calculateTourRevenue(tour),
      });
    }
    return toursWithRevenue;
  }
}
