import { HttpException, HttpStatus, Inject, Injectable, NotFoundException } from '@nestjs/common';
import { TypeOrmQueryService } from '@nestjs-query/query-typeorm';
import {  Department, Material  } from './material.entity';
import { InjectConnection, InjectRepository } from '@nestjs/typeorm';
import { Connection, Not, Repository } from 'typeorm';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';
import { TokenPayload } from 'src/types/token-payload.type';
import { ConfigService } from 'nestjs-config';
import { JwtService } from '@nestjs/jwt';
import {  CreateDepartmentDto,CreateMaterialConsumedDto,CreateMaterialDto,CreateMaterialIssuedDto,CreateMaterialRecievedDto,UpdateDepartmentDto, UpdateMaterialConsumedDto, UpdateMaterialDto, UpdateMaterialIssuedDto, UpdateMaterialRecievedDto } from './dto/material.dto';


@Injectable()
export class MaterialService extends TypeOrmQueryService<Material> {
    constructor(
        @InjectRepository(Material)
        private readonly materialRepository: Repository<Material>,
        private readonly jwtService: JwtService,
        private readonly config: ConfigService,
        @Inject(REQUEST) private readonly request: Request,
        @InjectConnection() private readonly connection: Connection
      ) {
        super(materialRepository, { useSoftDelete: true });
      }
      
      async getMaterials() {
        try {
          var query = await this.materialRepository.find();
          return query;
         
        } catch (ex) {
          throw ex;
        }
      }

      async getMaterialById(id: number) {

        try {
          var selectQuery = 'SELECT material.* from material where material.id ='+id;
          var material = await this.connection.query(selectQuery);
          
          if (!material) {
            throw new NotFoundException(`Material #${id} not found`);
          }

          return material;
          
         
        } catch (ex) {
          throw ex;
        }

      }


      async add(data: CreateMaterialDto) {
        try {
            const material:Material = new Material();
            material.name = data.name;
            material.price = data.price;
            material.quantity = data.quantity;
            material.type = data.type;
            material.uom = data.uom;
            material.vendor_id = data.vendor_id;
            material.batch_number = data.batch_number;
            material.brand = data.brand;
            material.description = data.description;
            material.expiry_date = data.expiry_date;
            material.created_at= data.created_at;
            var execute= await this.materialRepository.save(material);
            return "Material has been created";
        } catch (err) {
          throw err
        }
      }

      async update(id: number, data: UpdateMaterialDto) {
        try {
          const material:Material = new Material();
          material.name = data.name;
          material.price = data.price;
          material.quantity = data.quantity;
          material.type = data.type;
          material.uom = data.uom;
          material.vendor_id = data.vendor_id;
          material.batch_number = data.batch_number;
          material.brand = data.brand;
          material.description = data.description;
          material.expiry_date = data.expiry_date;
          material.updated_at= data.updated_at;           
          return await this.materialRepository.update(id, material);
      
        } catch (ex) {
          throw ex;
        }
      }

      
      async delete(id: number) {
        try {
          // return await this.usersRepository.delete(id);
          var delete_query = "Update material set status = 0 where id = "+id;
          var delete_query_execute = await this.connection.query(delete_query);
          if(delete_query_execute){
            return "deleted";
          }
        } catch (ex) {
          throw ex;
        }
      }

      //MaterialIssue

      async getAllMaterialIssue() {
        try {
          const assign = "SELECT * FROM pmt_tool.material_issued;"
          var query = await this.connection.query(assign);
          return query;
         
        } catch (ex) {
          throw ex;
        }
      }
  
      async getMaterialIssueById(id: number) {
  
        try {
          var selectQuery = 'SELECT material_issued.* from material_issued where material_issued.id ='+id;
          var assign = await this.connection.query(selectQuery);
          
          if (!assign) {
            throw new NotFoundException(`Material Issued #${id} not found`);
          }
  
          return assign;
          
         
        } catch (ex) {
          throw ex;
        }
  
      }
  
      async materialIssue(data: CreateMaterialIssuedDto) {
        
        try {
                                 
          var query = "insert into material_issued(name,brand,uom,quantity_issued,batch_number,type,created_at) Values ('"+data.name+"','"+data.brand+"','"+data.uom+"',"+data.quantity_issued+",'"+data.batch_number+"','"+data.type+"','"+data.created_at+"')";

      
          const inserted_query = await this.connection.query(query, [
             data.name,
             data.brand,
             data.uom,
             data.quantity_issued,
             data.batch_number,
             data.type,
             data.created_at

          ]);
            if(inserted_query){
              var last_inserted_id = inserted_query.insertId;
              
        
          }
          return inserted_query;
        } catch (err) {
          throw err
        }
      }
  
      async updateMaterialIssue(id: number, data: UpdateMaterialIssuedDto) {
        try {
    
            var update_query = "UPDATE material_issued set name= '" + data.name + "', type= '" + data.type + "',brand= '" + data.brand + "', uom= '" + data.uom + "',quantity_issued= '" + data.quantity_issued + "', batch_number= '" + data.batch_number + "',updated_at='"+data.updated_at+"' where id=" + id + " ";
            console.log(update_query)
            var execute_query = await this.connection.query(update_query);
            return "Material Issued has been updated"         
     
        } catch (ex) {
          throw ex;
        }
      }
  
      async deleteMaterialIssue(id: number) {
        try {
          var delete_query = "Update material_issued set status = 0 where id = "+id;
          var delete_query_execute = await this.connection.query(delete_query);
          if(delete_query_execute){
            return "deleted";
          }
        } catch (ex) {
          throw ex;
        }
      }

      
      //Material Consume

      async getAllMaterialConsume() {
        try {
          const assign = "SELECT * FROM pmt_tool.material_consumed;"
          var query = await this.connection.query(assign);
          return query;
         
        } catch (ex) {
          throw ex;
        }
      }
  
      async getMaterialConsumeById(id: number) {
  
        try {
          var selectQuery = 'SELECT material_consumed.* from material_consumed where material_consumed.id ='+id;
          var assign = await this.connection.query(selectQuery);
          
          if (!assign) {
            throw new NotFoundException(`Material Consumed #${id} not found`);
          }
  
          return assign;
          
         
        } catch (ex) {
          throw ex;
        }
  
      }
  
      async materialConsume(data: CreateMaterialConsumedDto) {
        
        try {
                                 
          var query = "insert into material_consumed(name,brand,uom,quantity_consumed,batch_number,type,created_at) Values ('"+data.name+"','"+data.brand+"','"+data.uom+"',"+data.quantity_consumed+",'"+data.batch_number+"','"+data.type+"','"+data.created_at+"')";

      
          const inserted_query = await this.connection.query(query, [
             data.name,
             data.brand,
             data.uom,
             data.quantity_consumed,
             data.batch_number,
             data.type,
             data.created_at

          ]);
            if(inserted_query){
              var last_inserted_id = inserted_query.insertId;
              
        
          }
          return inserted_query;
        } catch (err) {
          throw err
        }
      }
  
      async updateMaterialConsume(id: number, data: UpdateMaterialConsumedDto) {
        try {
    
            var update_query = "UPDATE material_consumed set name= '" + data.name + "', type= '" + data.type + "',brand= '" + data.brand + "', uom= '" + data.uom + "',quantity_consumed= '" + data.quantity_consumed + "', batch_number= '" + data.batch_number + "',updated_at='"+data.updated_at+"' where id=" + id + " ";
            console.log(update_query)
            var execute_query = await this.connection.query(update_query);
            return "Material Consumed has been updated"         
     
        } catch (ex) {
          throw ex;
        }
      }
  
      async deleteMaterialConsume(id: number) {
        try {
          var delete_query = "Update material_consumed set status = 0 where id = "+id;
          var delete_query_execute = await this.connection.query(delete_query);
          if(delete_query_execute){
            return "deleted";
          }
        } catch (ex) {
          throw ex;
        }
      }


      //MaterialRecieved

      async getAllMaterialRecieve() {
        try {
          const assign = "SELECT * FROM pmt_tool.material_recieved;"
          var query = await this.connection.query(assign);
          return query;
         
        } catch (ex) {
          throw ex;
        }
      }
  
      async getMaterialRecieveById(id: number) {
  
        try {
          var selectQuery = 'SELECT material_recieved.* from material_recieved where material_recieved.id ='+id;
          var assign = await this.connection.query(selectQuery);
          
          if (!assign) {
            throw new NotFoundException(`Material Recieved #${id} not found`);
          }
  
          return assign;
          
         
        } catch (ex) {
          throw ex;
        }
  
      }
  
      async materialRecieve(data: CreateMaterialRecievedDto) {
        
        try {
                                 
          var query = "insert into material_recieved(name,brand,uom,quantity_recieved,batch_number,type,created_at) Values ('"+data.name+"','"+data.brand+"','"+data.uom+"',"+data.quantity_recieved+",'"+data.batch_number+"','"+data.type+"','"+data.created_at+"')";

      
          const inserted_query = await this.connection.query(query, [
             data.name,
             data.brand,
             data.uom,
             data.quantity_recieved,
             data.batch_number,
             data.type,
             data.created_at

          ]);
            if(inserted_query){
              var last_inserted_id = inserted_query.insertId;
              
        
          }
          return inserted_query;
        } catch (err) {
          throw err
        }
      }
  
      async updateMaterialRecieve(id: number, data: UpdateMaterialRecievedDto) {
        try {
    
            var update_query = "UPDATE material_recieved set name= '" + data.name + "', type= '" + data.type + "',brand= '" + data.brand + "', uom= '" + data.uom + "',quantity_recieved= '" + data.quantity_recieved + "', batch_number= '" + data.batch_number + "',updated_at='"+data.updated_at+"' where id=" + id + " ";
            console.log(update_query)
            var execute_query = await this.connection.query(update_query);
            return "Material Recieved has been updated"         
     
        } catch (ex) {
          throw ex;
        }
      }
  
      async deleteMaterialRecieve(id: number) {
        try {
          var delete_query = "Update material_recieved set status = 0 where id = "+id;
          var delete_query_execute = await this.connection.query(delete_query);
          if(delete_query_execute){
            return "deleted";
          }
        } catch (ex) {
          throw ex;
        }
      }



      
      // //Material Consume

      // async getAllMaterialConsume() {
      //   try {
      //     const assign = "SELECT * FROM pmt_tool.material_consumed;"
      //     var query = await this.connection.query(assign);
      //     return query;
         
      //   } catch (ex) {
      //     throw ex;
      //   }
      // }
  
      // async getMaterialConsumeById(id: number) {
  
      //   try {
      //     var selectQuery = 'SELECT material_consumed.* from material_consumed where material_consumed.id ='+id;
      //     var assign = await this.connection.query(selectQuery);
          
      //     if (!assign) {
      //       throw new NotFoundException(`Material Consumed #${id} not found`);
      //     }
  
      //     return assign;
          
         
      //   } catch (ex) {
      //     throw ex;
      //   }
  
      // }
  
      // async materialConsume(data: CreateMaterialConsumedDto) {
        
      //   try {
                                 
      //     var query = "insert into material_consumed(name,brand,uom,quantity_consumed,batch_number,type,created_at) Values ('"+data.name+"','"+data.brand+"','"+data.uom+"',"+data.quantity_consumed+",'"+data.batch_number+"','"+data.type+"','"+data.created_at+"')";

      
      //     const inserted_query = await this.connection.query(query, [
      //        data.name,
      //        data.brand,
      //        data.uom,
      //        data.quantity_consumed,
      //        data.batch_number,
      //        data.type,
      //        data.created_at

      //     ]);
      //       if(inserted_query){
      //         var last_inserted_id = inserted_query.insertId;
              
        
      //     }
      //     return inserted_query;
      //   } catch (err) {
      //     throw err
      //   }
      // }
  
      // async updateMaterialConsume(id: number, data: UpdateMaterialConsumedDto) {
      //   try {
    
      //       var update_query = "UPDATE material_consumed set name= '" + data.name + "', type= '" + data.type + "',brand= '" + data.brand + "', uom= '" + data.uom + "',quantity_consumed= '" + data.quantity_consumed + "', batch_number= '" + data.batch_number + "',updated_at='"+data.updated_at+"' where id=" + id + " ";
      //       console.log(update_query)
      //       var execute_query = await this.connection.query(update_query);
      //       return "Material Consumed has been updated"         
     
      //   } catch (ex) {
      //     throw ex;
      //   }
      // }
  
      // async deleteMaterialConsume(id: number) {
      //   try {
      //     var delete_query = "Update material_consumed set status = 0 where id = "+id;
      //     var delete_query_execute = await this.connection.query(delete_query);
      //     if(delete_query_execute){
      //       return "deleted";
      //     }
      //   } catch (ex) {
      //     throw ex;
      //   }
      // }












      //Department

      async getDepartments() {
        try {
          const department = "SELECT * FROM pmt_tool.department;"
          var query = await this.connection.query(department);
          return query;
         
        } catch (ex) {
          throw ex;
        }
      }

      async getDepartmentById(id: number) {

        try {
          var selectQuery = 'SELECT department.* from department where department.id ='+id;
          var department = await this.connection.query(selectQuery);
          
          if (!department) {
            throw new NotFoundException(`Department #${id} not found`);
          }

          return department;
          
         
        } catch (ex) {
          throw ex;
        }

      }

      async addDepartment(data: CreateDepartmentDto) {
        try {
                                         
            var insert_query = "insert into department(department_name) Values ('"+data.department_name+"')";
            var inserted_query = await this.connection.query(insert_query);
            if(inserted_query){
              var last_inserted_id = inserted_query.insertId;
              
        
          }
          return inserted_query;
        } catch (err) {
          throw err
        }
      }

      async updateDepartment(id: number, data: UpdateDepartmentDto) {
        try {
    
            var insert_attachment_query = "UPDATE department set department_name= '" + data.department_name + "' where id=" + id + " ";
            var attachement_execute_query = await this.connection.query(insert_attachment_query);
            return "User has been updated"         
          // return await this.departmentRepository.update(id, department);
      
        } catch (ex) {
          throw ex;
        }
      }

      
      async delete_dept(id: number) {
        try {
          // return await this.usersRepository.delete(id);
          var delete_query = "Update department set status = 0 where id = "+id;
          var delete_query_execute = await this.connection.query(delete_query);
          if(delete_query_execute){
            return "deleted";
          }
        } catch (ex) {
          throw ex;
        }
      }

  

}
