import { Component, OnInit } from '@angular/core';
import { RegionService } from '../../shared/services/region.service';
import { ToastrService } from 'ngx-toastr';
import { NgxSpinnerService } from 'ngx-spinner';
import { PaginationService } from '../../shared/services/pagination.service';
import { TranslateService } from '@ngx-translate/core';
import { NgForm } from '@angular/forms';
import { Country } from '../../models/country';
import { States } from '../../models/state';
import { Districts } from '../../models/districts';
import { Cities } from '../../models/cities';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AppComponent } from '../../../app.component';

@Component({
  selector: 'app-region',
  templateUrl: './region.component.html',
  styleUrl: './region.component.scss'
})
export class RegionComponent implements OnInit {

  private token!: string;
  private startIndex!: number;
  private fetchRecord!: number;
  private stateStartIndex: number = 0;
  private districtStartIndex: number = 0;
  private cityStartIndex: number = 0;
  private take: number = 15;
  private activePage: number = 1;
  public countries: any[] = [];
  public states: any[] = [];
  public districts: any[] = [];
  public cities: any[] = [];
  private alertMessage!: string;
  public countryColumns!: ['name', 'action'];
  public countryPaginate: any = {};
  public statePaginate: any = {};
  public districtPaginate: any = {};
  public cityPaginate: any = {};
  public country: Country = new Country();
  public state: States = new States();
  public district: Districts = new Districts();
  public city: Cities = new Cities();
  public selectedCountry!: number;
  public selectedState!: number;
  public selectedDistrict!: number;
  public selectedCity!: number;
  public selectedStates: any[] = [];
  public selectedDistricts: any[] = [];
  public selectedCities: any[] = [];

  constructor(
    private regionService: RegionService,
    private toastrService: ToastrService,
    private spinnerService: NgxSpinnerService,
    private paginationService: PaginationService,
    private translate: TranslateService,
    private modalService: NgbModal
  ) { }

  async ngOnInit() {
    this.token = sessionStorage.getItem("SessionToken")!;
    await this.setPage(1);
    let lang = localStorage.getItem("selectedLanguage")!;;
    this.translate.use(lang);
  }

  public async setPage(pageNumber: number) {
    if (pageNumber > 0) {
      this.activePage = pageNumber;
      this.startIndex = (this.take * (this.activePage - 1));

      this.fetchRecord = this.take;
      await this.getCountries(1);
    }
  }

  async getCountries(pageNumber: any) {
    try {
      this.spinnerService.show();
      this.countries = [];
      this.states = [];
      this.districts = [];
      this.cities = [];
      const res = await this.regionService.getCountries(this.startIndex, this.fetchRecord, this.token);
      if (res && res.status === 200) {
        this.countries = res.recordList;
        let activePage = pageNumber;

        this.countryPaginate = this.paginationService.getPager(res.totalRecords, +activePage, this.take);
        if (this.countries && this.countries.length > 0) {
          this.countries[0].isSelected = true;
          await this.getState();
        }
      }
      this.spinnerService.hide();
    } catch (error: any) {
      this.spinnerService.hide();
      this.alertMessage = error;
      if (error?.message) {
        this.alertMessage = error.message
      }
      if (error?.error && error.error.message) {
        this.alertMessage = error.error.message
      }
      if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
        this.alertMessage = error.error.error.functionErrorMessage
      }
      this.toastrService.error(this.alertMessage)
    }
  }

  public async getState(e?: any, activePage?: number) {
    try {
      if (activePage) {
        this.stateStartIndex = (this.take * (activePage - 1));
      }
      activePage = activePage ? activePage : 1;
      this.states = [];
      this.districts = [];
      this.cities = [];
      this.spinnerService.show();
      if (e) {
        this.countries = this.countries.map(item => ({
          ...item,
          isSelected: false
        }));
        this.countries.find(c => c.id == (e.id ? e.id : e.target.value)).isSelected = true;
        this.countries = [...this.countries];
      }
      else {
        this.countries[0].isSelected = true;
      }
      this.selectedCountry = this.countries.find(c => c.isSelected).id;
      let res;
      res = await this.regionService.getStates(this.selectedCountry, this.stateStartIndex, this.fetchRecord, this.token);
      if (res && res.status == 200) {

        this.states = res.recordList;
        this.statePaginate = this.paginationService.getPager(res.totalRecords, +activePage, this.take);

        if (this.states && this.states.length > 0) {
          this.selectedState = this.states[0].id;
          await this.getDistrict();
        }
      }
      this.spinnerService.hide();
    } catch (error: any) {
      this.spinnerService.hide();
      this.alertMessage = error;
      if (error?.message) {
        this.alertMessage = error.message
      }
      if (error?.error && error.error.message) {
        this.alertMessage = error.error.message
      }
      if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
        this.alertMessage = error.error.error.functionErrorMessage
      }
      this.toastrService.error(this.alertMessage)
    }
  }

  public async getDistrict(e?: any, activePage?: number) {
    try {
      if (activePage) {
        this.districtStartIndex = (this.take * (activePage - 1));
      }
      this.districts = [];
      this.cities = [];
      activePage = activePage ? activePage : 1;

      this.spinnerService.show();
      if (e) {
        this.states = this.states.map(item => ({
          ...item,
          isSelected: false
        }));
        this.states.find(c => c.id == (e.id ? e.id : e.target.value)).isSelected = true;
        this.states = [...this.states];
      }
      else {
        this.states[0].isSelected = true;
      }
      this.selectedState = this.states.find(c => c.isSelected).id;
      let res = await this.regionService.getDistricts(this.selectedState, this.districtStartIndex, this.fetchRecord, this.token);
      if (res && res.status == 200) {
        this.districts = res.recordList;
        this.districtPaginate = this.paginationService.getPager(res.totalRecords, +activePage, this.take);
        if (this.districts && this.districts.length > 0) {
          this.selectedDistrict = this.districts[0].id;
          await this.getCity();
        }
      }
      this.spinnerService.hide();
    } catch (error: any) {
      this.spinnerService.hide();
      this.alertMessage = error;
      if (error?.message) {
        this.alertMessage = error.message
      }
      if (error?.error && error.error.message) {
        this.alertMessage = error.error.message
      }
      if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
        this.alertMessage = error.error.error.functionErrorMessage
      }
      this.toastrService.error(this.alertMessage)
    }
  }

  public async getCity(e?: any, activePage?: number) {
    try {
      if (activePage) {
        this.cityStartIndex = (this.take * (activePage - 1));
      }
      this.cities = []
      activePage = activePage ? activePage : 1
      this.spinnerService.show();
      if (e) {
        this.districts = this.districts.map(item => ({
          ...item,
          isSelected: false
        }));
        this.districts.find(c => c.id == (e.id ? e.id : e.target.value)).isSelected = true;
        this.districts = [...this.districts];
      }
      else {
        this.districts[0].isSelected = true;
      }
      this.selectedDistrict = this.districts.find(c => c.isSelected).id;
      let res = await this.regionService.getCities(this.selectedDistrict, this.cityStartIndex, this.fetchRecord, this.token);
      if (res && res.status == 200) {
        this.cities = res.recordList;
        this.cityPaginate = this.paginationService.getPager(res.totalRecords, +activePage, this.take);
      }
      this.spinnerService.hide();
    } catch (error: any) {
      this.spinnerService.hide();
      this.alertMessage = error;
      if (error?.message) {
        this.alertMessage = error.message
      }
      if (error?.error && error.error.message) {
        this.alertMessage = error.error.message
      }
      if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
        this.alertMessage = error.error.error.functionErrorMessage
      }
      this.toastrService.error(this.alertMessage)
    }
  }

  async saveCountry(form: NgForm) {
    if (form.valid) {
      await this.spinnerService.show();
      let res;
      try {
        if (this.country.id) {
          res = await this.regionService.updateCountry(this.country, this.token);
        } else {
          res = await this.regionService.insertCountry(this.country, this.token);
        }

        if (res && res.status === 200) {
          this.spinnerService.hide();
          this.modalService.dismissAll();
          await this.setPage(1);
        }
      } catch (error: any) {
        this.spinnerService.hide();
        this.alertMessage = error;
        if (error?.message) {
          this.alertMessage = error.message
        }
        if (error?.error && error.error.message) {
          this.alertMessage = error.error.message
        }
        if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
          this.alertMessage = error.error.error.functionErrorMessage
        }
        this.toastrService.error(this.alertMessage)
      }
    }
  }

  async saveState(form: NgForm) {
    if (form.valid) {
      await this.spinnerService.show();
      let res;
      try {
        this.state.isActive = this.state.isActive ? true : false;
        this.state.isDelete = this.state.isDelete ? true : false
        if (this.state.id) {

          res = await this.regionService.updateState(this.state, this.token);
        } else {
          res = await this.regionService.insertState(this.state, this.token);
        }

        if (res && res.status === 200) {
          this.spinnerService.hide();
          this.modalService.dismissAll();
          await this.setPage(1);
        }
      } catch (error: any) {
        this.spinnerService.hide();
        this.alertMessage = error;
        if (error?.message) {
          this.alertMessage = error.message
        }
        if (error?.error && error.error.message) {
          this.alertMessage = error.error.message
        }
        if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
          this.alertMessage = error.error.error.functionErrorMessage
        }
        this.toastrService.error(this.alertMessage)
      }
    }
  }

  async saveDistrict(form: NgForm) {
    if (form.valid) {
      await this.spinnerService.show();
      let res;
      try {
        this.district.isActive = this.district.isActive ? true : false;
        this.district.isDelete = this.district.isDelete ? true : false
        if (this.district.id) {
          res = await this.regionService.updateDistrict(this.district, this.token);
        } else {
          res = await this.regionService.insertDistrict(this.district, this.token);
        }

        if (res && res.status === 200) {
          this.spinnerService.hide();
          this.modalService.dismissAll();
          await this.setPage(1);
        }
      } catch (error: any) {
        this.spinnerService.hide();
        this.alertMessage = error;
        if (error?.message) {
          this.alertMessage = error.message
        }
        if (error?.error && error.error.message) {
          this.alertMessage = error.error.message
        }
        if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
          this.alertMessage = error.error.error.functionErrorMessage
        }
        this.toastrService.error(this.alertMessage)
      }
    }
  }

  async saveCity(form: NgForm) {
    if (form.valid) {
      await this.spinnerService.show();
      let res;
      try {
        this.city.isActive = this.city.isActive ? true : false;
        this.city.isDelete = this.city.isDelete ? true : false
        if (this.city.id) {
          res = await this.regionService.updateCity(this.city, this.token);
        } else {
          res = await this.regionService.insertCity(this.city, this.token);
        }

        if (res && res.status === 200) {
          this.spinnerService.hide();
          this.modalService.dismissAll();
          await this.setPage(1);

        }
      } catch (error: any) {
        this.spinnerService.hide();
        this.alertMessage = error;
        if (error?.message) {
          this.alertMessage = error.message
        }
        if (error?.error && error.error.message) {
          this.alertMessage = error.error.message
        }
        if (error?.error && error.error.error && error.error.error.functionErrorMessage) {
          this.alertMessage = error.error.error.functionErrorMessage
        }
        this.toastrService.error(this.alertMessage)
      }
    }
  }

  public closeDialog() {
    this.modalService.dismissAll();
  }

  public modalOpen(countryModal: any) {
    this.country = new Country();
    this.state = new States();
    this.city = new Cities();
    this.district = new Districts();
    this.modalService.open(countryModal);
  }

  public editCountry(countrymodal: any, country: Country) {
    this.country = country;
    this.modalService.open(countrymodal)
  }

  public editState(stateModal: any, state: States) {
    this.state = state;
    this.modalService.open(stateModal)
  }

  public async editDistrict(districtModal: any, district: Districts) {
    this.district = district;
    let res = await this.regionService.getStates(district.countryId, null, null, this.token);
    if (res && res.status == 200) {
      this.selectedStates = res.recordList;
    }
    this.modalService.open(districtModal)
  }

  public async editCity(cityModal: any, city: Cities) {
    this.city = city;
    let res = await this.regionService.getStates(city.countryId, null, null, this.token);
    if (res && res.status == 200) {
      this.selectedStates = res.recordList;
    }
    let districtres = await this.regionService.getDistricts(city.districtId, null, null, this.token);
    if (districtres && districtres.status == 200) {
      this.selectedDistricts = districtres.recordList;
    }
    this.modalService.open(cityModal)
  }

  public async getSelectedState(e: any) {
    let res = await this.regionService.getStates(e.id, null, null, this.token);
    if (res && res.status == 200) {
      this.selectedStates = res.recordList;
    }
  }

  public async getSelectedDistrict(e: any) {
    let res = await this.regionService.getStates(e.id, null, null, this.token);
    if (res && res.status == 200) {
      this.selectedStates = res.recordList;
    }
    let districtres = await this.regionService.getDistricts(this.selectedStates[0].id, null, null, this.token);
    if (districtres && districtres.status == 200) {
      this.selectedDistricts = districtres.recordList;
    }
  }

  public async downloadCsv() {
    try {
      this.spinnerService.show();
      let res = await this.regionService.getAllRegionData(this.token);
      let customers: any = [];
      if (res && res.status == 200) {
        customers = res.recordList;
        if (customers && customers.length > 0) {
          for (let index = 0; index < customers.length; index++) {
            customers[index].code = customers[index].permanentCode ? customers[index].permanentCode : customers[index].temporaryCode
          }
        }
      }
      AppComponent.text = "Generate CSV";
      this.downloadFile(customers);
      this.spinnerService.hide();
    } catch (error: any) {
      this.spinnerService.hide();
      this.toastrService.error(error);
    }
  }

  private downloadFile(data: any) {
    let csvData = this.ConvertToCSV(data, ['countryId', 'countryName', 'isoCode', 'isoCode3', 'dialCode', 'stateId', 'stateName', 'districtId', 'districtName', 'cityId', 'cityName', 'pincode']);
    console.log(csvData)
    let blob = new Blob(['\ufeff' + csvData], { type: 'text/csv;charset=utf-8;' });
    let dwldLink = document.createElement("a");
    let url = URL.createObjectURL(blob);
    let isSafariBrowser = navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1;
    if (isSafariBrowser) {  //if Safari open in new window to save file with random filename.
      dwldLink.setAttribute("target", "_blank");
    }
    dwldLink.setAttribute("href", url);
    let fileName = 'Customer_export_' + new Date().getDate() + "-" + (new Date().getMonth() + 1) + "-" + new Date().getFullYear() + " " + new Date().getTime();
    dwldLink.setAttribute("download", fileName + ".csv");
    dwldLink.style.visibility = "hidden";
    document.body.appendChild(dwldLink);
    dwldLink.click();
    document.body.removeChild(dwldLink);
  }

  private ConvertToCSV(data: any, fields: any) {
    let array = typeof data != 'object' ? JSON.parse(data) : data;
    let str = '';
    // str += "Sale Order On Date " + this.parameter.dateFrom.getDate() + "/" + (this.parameter.dateFrom.getMonth() + 1) + "/" + this.parameter.dateFrom.getFullYear() + " " + ((new Date(this.parameter.dateFrom)).getHours() < 10 ? '0' : '') + this.parameter.dateFrom.getHours() + ":" + ((new Date(this.parameter.dateFrom)).getMinutes() < 10 ? '0' : '') + this.parameter.dateFrom.getMinutes() + " TO " + (this.parameter.dateFrom.getDate()) + "/" + (this.parameter.dateFrom.getMonth() + 1) + "/" + this.parameter.dateFrom.getFullYear() + " " + ((new Date(this.parameter.dateTo)).getHours() < 10 ? '0' : '') + this.parameter.dateTo.getHours() + ":" + ((new Date(this.parameter.dateTo)).getMinutes() < 10 ? '0' : '') + this.parameter.dateTo.getMinutes() + '\r\n';
    let row = '';
    for (let index in fields) {
      row += fields[index] + ',';
    }
    row = row.slice(0, -1);
    let line = ''
    str += row + '\r\n';
    console.log(array.length);

    for (let i = 0; i < array.length; i++) {
      line += '\n' + array[i].countryId + ", " + array[i].countryName + ", " + array[i].isoCode + ", " + array[i].isoCode3 + ", " + array[i].dialCode + ", " + array[i].stateId + ", " + array[i].stateName + ", " + array[i].districtId + ", " + array[i].districtName + ", " + array[i].cityId + ", " + array[i].cityName + ", " + array[i].pincode;
    }
    str += line + '\r\n';
    return str;
  }

  public updateData(e: any) {
    let file = e.target.files[0];
    if (file) {
      const fileReader = new FileReader();
      fileReader.onload = async () => {
        const csvOutput = fileReader.result;
        const lines = csvOutput!.toString().split("\n");
        const headers = lines[0].split(",");
        const result = [];

        console.log(lines);
        for (let i = 1; i < lines.length; i++) {
          if (lines[i]) {
            const obj: any = {};
            const currentLine = lines[i].split(",");

            for (let j = 0; j < headers.length; j++) {
              obj[headers[j].trim()] = currentLine[j].trim();
            }

            result.push(obj);
          }
        }
        if (result && result.length > 0) {
          try {
            let res = await this.regionService.updateRegionData(result, this.token);
            if (res && res.status == 200) {
              await this.getCountries(1);
            }
          } catch (error: any) {
            this.toastrService.error(error);
          }
        };


      };
      fileReader.readAsText(file);
    }
  }
}
