import { Controller, Get } from '@nestjs/common';
import { CustomerService } from './customer.service';
import { MessagePattern, RpcException } from '@nestjs/microservices';
import { CustomerverificationsService } from './customerverifications/customerverifications.service';

@Controller()
export class CustomerController {
  constructor(
    private readonly customerService: CustomerService,
    private readonly customerVerificationService: CustomerverificationsService,
  ) {}

  @MessagePattern({ cmd: 'customer_get_all' })
  async getAll(data: { protocol: string; host: string }): Promise<any> {
    try {
      const { protocol, host } = data;
      const baseurl1 = `${protocol}://${host}/uploads/customer/NIC_Back/`;
      const baseurl2 = `${protocol}://${host}/uploads/customer/NIC_Front/`;
      const baseurl3 = `${protocol}://${host}/uploads/customer/Photos/`;
      const baseurl4 = `${protocol}://${host}/uploads/customer/salary_slips/`;
      const baseurl5 = `${protocol}://${host}/uploads/customer/utility_bills/`;
      console.log('ok getall is calling!');

      const customers = await this.customerService.getAll();

      const data2 = await Promise.all(
        customers.map(async (item) => {
          const NIC_BackUrl = item.NIC_Back_Path
            ? baseurl1 + item.NIC_Back_Path
            : null;

          const NIC_Front_Path_Url = item.NIC_Front_Path
            ? baseurl2 + item.NIC_Front_Path
            : null;
          const Photo_Path_Url = item.Photo_Path
            ? baseurl3 + item.Photo_Path
            : null;

          const Salary_Slip_Path_Url = item.Salary_Slip_Path
            ? baseurl4 + item.Salary_Slip_Path
            : null;
          const Utility_Bill_Path_Url = item.Utility_Bill_Path
            ? baseurl5 + item.Utility_Bill_Path
            : null;

          return {
            ...item,
            NIC_BackUrl,
            NIC_Front_Path_Url,
            Photo_Path_Url,
            Salary_Slip_Path_Url,
            Utility_Bill_Path_Url,
          };
        }),
      );
      return data2;
    } catch (err) {
      console.error('Error in customer_get_all:', err);
      throw new RpcException('Failed to retrieve customers');
    }
  }

  @MessagePattern({ cmd: 'customer_get_by_id' })
  async getById(data: {
    id: number;
    protocol: string;
    host: string;
  }): Promise<any> {
    try {
      const { id, protocol, host } = data;
      const baseurl1 = `${protocol}://${host}/uploads/customer/NIC_Back/`;
      const baseurl2 = `${protocol}://${host}/uploads/customer/NIC_Front/`;
      const baseurl3 = `${protocol}://${host}/uploads/customer/Photos/`;
      const baseurl4 = `${protocol}://${host}/uploads/customer/salary_slips/`;
      const baseurl5 = `${protocol}://${host}/uploads/customer/utility_bills/`;
      console.log('ok getall is calling!');

      const customers = await this.customerService.getById(id);

      const NIC_BackUrl = customers.NIC_Back_Path
        ? baseurl1 + customers.NIC_Back_Path
        : null;

      const NIC_Front_Path_Url = customers.NIC_Front_Path
        ? baseurl2 + customers.NIC_Front_Path
        : null;
      const Photo_Path_Url = customers.Photo_Path
        ? baseurl3 + customers.Photo_Path
        : null;

      const Salary_Slip_Path_Url = customers.Salary_Slip_Path
        ? baseurl4 + customers.Salary_Slip_Path
        : null;
      const Utility_Bill_Path_Url = customers.Utility_Bill_Path
        ? baseurl5 + customers.Utility_Bill_Path
        : null;

      return {
        ...customers,
        NIC_BackUrl,
        NIC_Front_Path_Url,
        Photo_Path_Url,
        Salary_Slip_Path_Url,
        Utility_Bill_Path_Url,
      };
    } catch (err) {
      console.error('Error in customer_get_all:', err);
      throw new RpcException('Failed to retrieve customers');
    }
  }

  @MessagePattern({ cmd: 'customer_create' })
  async create(data: {
    body: any;
    files: {
      Salary_Slip?: Express.Multer.File[];

      NIC_Front?: Express.Multer.File[];

      NIC_Back?: Express.Multer.File[];
      Utility_Bill?: Express.Multer.File[];

      Photo?: Express.Multer.File[];
    };
  }): Promise<any> {
    try {
      console.log('ok normal controller is calling!');
      const { body, files } = data;
      const Salary_Slip = files.Salary_Slip?.[0];
      const NIC_Front = files.NIC_Front?.[0];
      const NIC_Back = files.NIC_Back?.[0];
      const Utility_Bill = files.Utility_Bill?.[0];
      const Photo = files.Photo?.[0];

      const result = await this.customerService.create(
        body,
        Salary_Slip,
        NIC_Front,
        NIC_Back,
        Utility_Bill,
        Photo,
      );
      return result;
    } catch (err) {
      console.log(err);
      throw new RpcException('Failed to add customer');
    }
  }

  @MessagePattern({ cmd: 'customer_update' })
  async update(data: {
    id: number;
    body: any;
    files: {
      Salary_Slip?: Express.Multer.File[];
      NIC_Front?: Express.Multer.File[];
      NIC_Back?: Express.Multer.File[];
      Utility_Bill?: Express.Multer.File[];
      Photo?: Express.Multer.File[];
    };
  }): Promise<any> {
    try {
      const { id, body, files } = data;

      const Salary_Slip = files.Salary_Slip?.[0];
      const NIC_Front = files.NIC_Front?.[0];
      const NIC_Back = files.NIC_Back?.[0];
      const Utility_Bill = files.Utility_Bill?.[0];
      const Photo = files.Photo?.[0];

      return await this.customerService.update(
        id,
        body,
        Salary_Slip,
        NIC_Front,
        NIC_Back,
        Utility_Bill,
        Photo,
      );
    } catch (err) {
      console.error(err);
      throw new RpcException('Failed to update customer');
    }
  }

  @MessagePattern({ cmd: 'get_pending_verification_list' })
  async getPendingVerification(data: { protocol: string; host: string }) {
    try {
      const { protocol, host } = data;
      const customers = await this.customerService.getPendingVerification();
      const processedCustomers = await Promise.all(
        customers.map(async (customer) => {
          const verifiedDocs: { name: string; url: string; Status: number }[] =
            [];
          const notVerifiedDocs: {
            name: string;
            url: string;
            Status: number;
          }[] = [];
          const rejectedDocs: { name: string; url: string; Status: number }[] =
            [];
          const baseurl1 = `${protocol}://${host}/uploads/customer/NIC_Back/`;
          const baseurl2 = `${protocol}://${host}/uploads/customer/NIC_Front/`;
          const baseurl3 = `${protocol}://${host}/uploads/customer/Photos/`;
          const baseurl4 = `${protocol}://${host}/uploads/customer/salary_slips/`;
          const baseurl5 = `${protocol}://${host}/uploads/customer/utility_bills/`;

          const rejectedCount =
            await this.customerService.getRejectedDocByCustomerId(
              customer.idCustomer,
            );

          if (customer.NIC_Back_Path) {
            const url = baseurl1 + customer.NIC_Back_Path;
            if (customer.NIC_Back_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            } else if (customer.NIC_Back_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            } else if (customer.NIC_Back_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            }
          }

          if (customer.Utility_Bill_Path) {
            const url = baseurl5 + customer.Utility_Bill_Path;
            if (customer.Utility_Bill_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            } else if (customer.Utility_Bill_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            } else if (customer.Utility_Bill_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            }
          }

          if (customer.Photo_Path) {
            const url = baseurl3 + customer.Photo_Path;
            if (customer.Photo_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            } else if (customer.Photo_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            } else if (customer.Photo_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            }
          }
          if (customer.Salary_Slip_Path) {
            const url = baseurl4 + customer.Salary_Slip_Path;
            if (customer.Salary_Slip_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            } else if (customer.Salary_Slip_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            } else if (customer.Salary_Slip_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            }
          }

          if (customer.NIC_Front_Path) {
            const url = baseurl2 + customer.NIC_Front_Path;
            if (customer.NIC_Front_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            } else if (customer.NIC_Front_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            } else if (customer.NIC_Front_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            }
          }

          return {
            idCustomer: customer.idCustomer,
            First_Name: customer.First_Name,
            Last_Name: customer.Last_Name,
            verifiedDocs,
            notVerifiedDocs,
            rejectedCount,
          };
        }),
      );

      return processedCustomers;
    } catch (err) {
      console.log(err);
      throw new RpcException('Failed to fetch pending verifications');
    }
  }

  @MessagePattern({ cmd: 'get_pending_verification_list_by_customer_id' })
  async getPendingVerificationByCustomerId(data: {
    protocol: string;
    host: string;
    id: number;
  }) {
    try {
      const { protocol, host, id } = data;
      const customers =
        await this.customerService.getPendingVerificationByCustomerId(id);
      const processedCustomers = await Promise.all(
        customers.map(async (customer) => {
          const verifiedDocs: { name: string; url: string; Status: number }[] =
            [];
          const notVerifiedDocs: {
            name: string;
            url: string;
            Status: number;
          }[] = [];

          const rejectedDocs: { name: string; url: string; Status: number }[] =
            [];

          const baseurl1 = `${protocol}://${host}/uploads/customer/NIC_Back/`;
          const baseurl2 = `${protocol}://${host}/uploads/customer/NIC_Front/`;
          const baseurl3 = `${protocol}://${host}/uploads/customer/Photos/`;
          const baseurl4 = `${protocol}://${host}/uploads/customer/salary_slips/`;
          const baseurl5 = `${protocol}://${host}/uploads/customer/utility_bills/`;

          const rejectedCount =
            await this.customerService.getRejectedDocByCustomerId(
              customer.idCustomer,
            );

          if (customer.NIC_Back_Path) {
            const url = baseurl1 + customer.NIC_Back_Path;
            if (customer.NIC_Back_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            } else if (customer.NIC_Back_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            } else if (customer.NIC_Back_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'NIC_Back_Path',
                url,
                Status: customer.NIC_Back_Verification_Status,
              });
            }
          }

          if (customer.Utility_Bill_Path) {
            const url = baseurl5 + customer.Utility_Bill_Path;
            if (customer.Utility_Bill_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            } else if (customer.Utility_Bill_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            } else if (customer.Utility_Bill_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Utility_Bill_Path',
                url,
                Status: customer.Utility_Bill_Verification_Status,
              });
            }
          }

          if (customer.Photo_Path) {
            const url = baseurl3 + customer.Photo_Path;
            if (customer.Photo_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            } else if (customer.Photo_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            } else if (customer.Photo_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Photo_Path',
                url,
                Status: customer.Photo_Verification_Status,
              });
            }
          }

          if (customer.Salary_Slip_Path) {
            const url = baseurl4 + customer.Salary_Slip_Path;
            if (customer.Salary_Slip_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            } else if (customer.Salary_Slip_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            } else if (customer.Salary_Slip_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'Salary_Slip_Path',
                url,
                Status: customer.Salary_Slip_Verification_Status,
              });
            }
          }

          if (customer.NIC_Front_Path) {
            const url = baseurl2 + customer.NIC_Front_Path;
            if (customer.NIC_Front_Verification_Status == 1) {
              verifiedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            } else if (customer.NIC_Front_Verification_Status == 0) {
              notVerifiedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            } else if (customer.NIC_Front_Verification_Status == 2) {
              rejectedDocs.push({
                name: 'NIC_Front_Path',
                url,
                Status: customer.NIC_Front_Verification_Status,
              });
            }
          }

          return {
            idCustomer: customer.idCustomer,
            First_Name: customer.First_Name,
            Last_Name: customer.Last_Name,
            verifiedDocs,
            notVerifiedDocs,
            rejectedCount,
          };
        }),
      );
      return processedCustomers;
    } catch (err) {
      console.log(err);
      throw new RpcException('Failed to fetch pending verifications');
    }
  }

  //in here need to remember rejection status is 2 and approved status is 1
  @MessagePattern({ cmd: 'verify_document_by_name' })
  async verifyDocumentByName(data: { id: number; name: string; body: any }) {
    try {
      console.log('Normal micro controller executing');
      const { id, name, body } = data;

      const { Status, Note, Date_Time, User_idUser } = body;
      console.log('Passing status is : ', Status);
      console.log('Passing Note is : ', Note);

      let fieldname: string;

      if (name == 'Salary_Slip_Path') {
        fieldname = 'Salary_Slip_Verification_Status';
      } else if (name == 'NIC_Front_Path') {
        fieldname = 'NIC_Front_Verification_Status';
      } else if (name == 'NIC_Back_Path') {
        fieldname = 'NIC_Back_Verification_Status';
      } else if (name == 'Utility_Bill_Path') {
        fieldname = 'Utility_Bill_Verification_Status';
      } else if (name == 'Photo_Path') {
        fieldname = 'Photo_Verification_Status';
      } else {
        throw new RpcException({
          message: 'Please send a valid path name',
          statusCode: 400,
        });
      }
      console.log('*');
      await this.customerService.verifyDocumentByName(id, fieldname, Status);

      let Evidence_Type = 'no name';
      if (Status == 1) {
        Evidence_Type = 'Approved';
      } else if (Status == 2) {
        Evidence_Type = 'Rejected';
      }

      await this.customerVerificationService.addCustomerVerification(
        id,
        Date_Time,
        Evidence_Type,
        Status,
        Note,
        'Manual Process',
        User_idUser,
        name,
      );
      return {
        message: 'Document Verification Completed',
        success: true,
      };
    } catch (err) {
      console.log(err);

      if (err instanceof RpcException) {
        throw err;
      }

      throw new RpcException('Failed to change status of the document!');
    }
  }
}
