import {
  Controller,
  Body,
  Patch,
  Param,
  ParseIntPipe,
  UseGuards,
  Get,
  Query,
  Delete,
  NotFoundException,
  Post,
  Res,
  Request,
  BadRequestException,
} from '@nestjs/common';
import { EquipoService } from './equipo.service';
import { UpdateEquipoDto } from './dto/update-equipo.dto';
import { AuthGuard } from '@nestjs/passport';
import { CreateEquipoDto } from './dto/create-equipo.dto';
import type { Response } from 'express';
import { FiltrosGraficaDto, FiltrosTablaDto } from './dto/grafica.dto';

@Controller('equipos')
export class EquipoController {
  constructor(private readonly equipoService: EquipoService) { }
  @UseGuards(AuthGuard('jwt'))
  @Get('buscar')
  async buscarEquipos(
    @Query() filtros: any,
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 10,
  ) {
    return this.equipoService.buscarEquipos(filtros, +page, +limit);
  }

  @Post('grafica/:tipo')
  async grafica(
    @Param("tipo") tipo: 'antiguedad' | 'uso' | 'so' | 'procesador',
    @Body() filtros: FiltrosGraficaDto
  ) {
    return this.equipoService.grafica(tipo, filtros);
  }

  @Post('tabla')
  async tabla(
    @Body() filtros: FiltrosTablaDto
  ) {
    return this.equipoService.tabla(filtros);
  }

  @Post('tabla/count')
  async tablacount(
    @Body() filtros: FiltrosTablaDto
  ) {
    return this.equipoService.tablaCount(filtros);
  }

  @Post('excel/tabla')
  async exceltabla(
    @Res() res: Response,
    @Body() filtros: FiltrosTablaDto
  ) {
    const buffer = await this.equipoService.tablaExcel(filtros);

    res.set({
      'Content-Type':
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': 'attachment; filename=tabla.xlsx',
    });

    res.send(buffer);
  }

  @Post('excel/tabla/count')
  async exceltablacount(
    @Res() res: Response,
    @Body() filtros: FiltrosGraficaDto
  ) {
    const buffer = await this.equipoService.tablaCountExcel(filtros);

    res.set({
      'Content-Type':
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': 'attachment; filename=tabla.xlsx',
    });

    res.send(buffer);
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('buscar/:inv')
  async serch(@Param('inv') inv: string) {
    return await this.equipoService.findEquipo(inv);
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('crear')
  async create(@Body() Equipo: CreateEquipoDto, @Request() req) {
    return await this.equipoService.create(Equipo, req.user.id);
  }
  @UseGuards(AuthGuard('jwt'))
  @Patch('update/:id')
  update(
    @Request() req,
    @Param('id', ParseIntPipe) id: number,
    @Body() equipoNuevo: UpdateEquipoDto,
  ) {
    return this.equipoService.updateEquipo(equipoNuevo, id, req.user.id);
  }

  @UseGuards(AuthGuard('jwt'))
  @Delete(':id')
  async deleteEquipo(@Param('id', ParseIntPipe) id_equipo: string) {
    try {
      return await this.equipoService.deleteEquipo(id_equipo);
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('usos')
  findUsos() {
    return this.equipoService.findAllUsos();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('marcas')
  findMarcas() {
    return this.equipoService.findAllMarcas();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('estados')
  findEstados() {
    return this.equipoService.findAllEstados();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('adscripciones')
  findAdscripciones() {
    return this.equipoService.findAllAdscripciones();
  }
  @UseGuards(AuthGuard('jwt'))
  @Get('tipos-equipo')
  findTiposEquipo() {
    return this.equipoService.findAllTiposEquipo();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('sistemas-operativos')
  findSistemasOperativos() {
    return this.equipoService.findAllSistemasOperativos();
  }
  @UseGuards(AuthGuard('jwt'))
  @Get('procesadores')
  findProcesadores() {
    return this.equipoService.findAllProcesadores();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('laboratorios')
  findLaboratorios() {
    return this.equipoService.findAllLaboratorios();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('proyectos')
  findProyectos() {
    return this.equipoService.findAllProyectos();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('perifericos')
  findPerifericos() {
    return this.equipoService.findAllPerifericos();
  }

  @UseGuards(AuthGuard('jwt'))
  @Get('procesador-tipo-equipos')
  findProcesadorTipoEquipos() {
    return this.equipoService.findAllProcesadorTipoEquipos();
  }

  // @Post('daily')
  // async daily() {
  //   return await this.equipoService.llenadoDeAntiguedad();
  // }

  @UseGuards(AuthGuard('jwt'))
  @Get('reporteXLSX')
  async generarReporte(@Res({ passthrough: true }) res: Response) {
    try {
      await this.equipoService.createEcxel(res);
    } catch (error) {
      console.error('Error al generar el Excel:', error);
      res.status(500).send('Error al generar el archivo Excel');
    }
  }

  @Post('reporte')
  async reporte(@Body() estado: string[]) {
    try {
      return await this.equipoService.generar_reporte(estado);
    } catch (error) {
      throw new BadRequestException('Error al generar el reporte:', error);
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/tipoEquipos_tipoUso')
  async reportetipoEquipos_tipoUso(@Body() estado: string[]) {
    try {
      return await this.equipoService.contar_tipoEquipos_tipoUso(estado);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte tipoEquipos_tipoUso:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/tipoEquipos_sistemasOperativos')
  async reportetipoEquipos_sistemasOperativos(@Body() estado: string[]) {
    try {
      return await Promise.all([
        this.equipoService.contar_tipoEquipos_sistemasOperativos(
          equpos_pc,
          estado,
        ),
        this.equipoService.contar_tipoEquipos_sistemasOperativos(
          [estritorio_mac],
          estado,
        ),
        this.equipoService.contar_tipoEquipos_sistemasOperativos(
          portatiles,
          estado,
        ),
        this.equipoService.contar_tipoEquipos_sistemasOperativos(
          [portatiles_mac],
          estado,
        ),
        this.equipoService.contar_tipoEquipos_sistemasOperativos(
          [servidor],
          estado,
        ),
      ]);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte tipoEquipos_sistemasOperativos:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/tipoEquipos_procesador')
  async reportetipoEquipos_procesador(@Body() estado: string[]) {
    try {
      return await Promise.all([
        this.equipoService.contar_tipoEquipos_procesador(equpos_pc, estado),
        this.equipoService.contar_tipoEquipos_procesador(
          [estritorio_mac],
          estado,
        ),
        this.equipoService.contar_tipoEquipos_procesador(portatiles, estado),
        this.equipoService.contar_tipoEquipos_procesador(
          [portatiles_mac],
          estado,
        ),
        this.equipoService.contar_tipoEquipos_procesador([servidor], estado),
      ]);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte tipoEquipos_procesador:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/tipoEquipos_antiguedad')
  async reportetipoEquipos_antiguedad(@Body() estado: string[]) {
    try {
      return await this.equipoService.contar_tipoEquipos_antiguedad(estado);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte contar_tipoEquipos_antiguedad:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/garantia')
  async reportegarantia(@Body() estado: string[]) {
    try {
      return await Promise.all([
        this.equipoService.garantia(escritorio, estado),
        this.equipoService.garantia(portatil, estado),
        this.equipoService.garantia([servidor], estado),
      ]);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte garantia:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/equipos_impesion_group/impresoras')
  async reporteequipos_impesion_group(@Body() estado: string[]) {
    try {
      return await this.equipoService.equipos_impesion_group(
        impresoras,
        estado,
      );
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte impesion_group impresoras:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/equipos_impesion_group/dijitales')
  async reporteequipos_impesion_group_dijitales(@Body() estado: string[]) {
    try {
      return await this.equipoService.equipos_impesion_group(dijitales, estado);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte impesion_group dijitales:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/contar_periferico_tipoUso/impresoras')
  async reporte_contar_periferico_tipoUso_impresoras(@Body() estado: string[]) {
    try {
      return await this.equipoService.contar_periferico_tipoUso(
        impresoras,
        estado,
      );
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte periferico_tipoUso impresoras:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/contar_periferico_tipoUso/dijtales')
  async reporte_contar_periferico_tipoUso_dijtales(@Body() estado: string[]) {
    try {
      return await this.equipoService.contar_periferico_tipoUso(
        dijitales,
        estado,
      );
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte periferico_tipoUso dijtales:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/contar_perifericos_antiguedad')
  async reporte_contar_perifericos_antiguedad(@Body() estado: string[]) {
    try {
      return await this.equipoService.contar_perifericos_antiguedad(
        impresoras,
        dijitales,
        estado,
      );
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte perifericos_antiguedad:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/contar_laboratorio')
  async reporte_contar_laboratorio(@Body() estado: string[]) {
    try {
      return await this.equipoService.laboratorio_equipos(estado);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte perifericos_antiguedad:',
        error,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @Post('reporte/contar_proyecto')
  async reporte_contar_proyecto(@Body() estado: string[]) {
    try {
      return await this.equipoService.proyecto_equipos(estado);
    } catch (error) {
      throw new BadRequestException(
        'Error al generar el reporte perifericos_antiguedad:',
        error,
      );
    }
  }

  @Get('ranking/:year')
  async ranking(@Param('year') year: string) {
    return this.equipoService.ranking(Number(year));
  }
}

let escritorio = ['ESCRITORIO PC', 'ESCRITORIO MAC OS ', 'ESCRITORIO LINUX'];
let portatil = [
  'PORTÁTILES WINDOWS',
  'PORTÁTILES CHROMEBOOK',
  'PORTÁTILES MAC OS',
];

let equipos_mac = ['ESCRITORIO MAC OS ', 'PORTÁTILES MAC OS'];

let equpos_pc = ['ESCRITORIO PC', 'ESCRITORIO LINUX'];
let estritorio_mac = 'ESCRITORIO MAC OS ';
let portatiles_mac = 'PORTÁTILES MAC OS';

let portatiles = ['PORTÁTILES WINDOWS', 'PORTÁTILES CHROMEBOOK'];

let tabletas = ['TABLETA ANDROID', 'TABLETA iPAD OS'];

let impresoras = [
  'INYECCIÓN TINTA',
  'LÁSER DE ALTO VOLUMEN B/N',
  'LÁSER DE ALTO VOLUMEN COLOR',
  'LÁSER PEQUEÑA B/N',
  'LÁSER PEQUEÑA COLOR',
  'MATRIZ DE PUNTOS',
  'MULTIFUNCIONALES',
  'IMPRESORA TÉRMICA',
  'IMPRESORA CREDENCIALES',
  'PLOTTER',
];

let dijitales = [
  '3D',
  'DIGITALIZADOR DE CAMA PLANA PARA OFICINA',
  'DIGITALIZADOR DE GRAN VOLUMEN',
  'DIGITALIZADOR CON ALIMENTADOR DE HOJAS PARA OFICINA',
];

let servidor = 'SERVIDOR';
