import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment';
import { forkJoin, of } from 'rxjs';
import { CommonFunctionService } from 'src/app/core/common/common-function.service';
import { ValidationService } from 'src/app/core/common/validation.service';
import { API } from 'src/app/core/services/api.service';
import { OverViewData } from 'src/app/core/models/hotelService/OverViewData/RoomsOverView.model';
@Component({
  selector: 'overview',
  templateUrl: './overview.component.html',
})
export class OverviewComponent implements OnInit {

  SeasonResult;
  @ViewChild('tableContainer') tableContainer: ElementRef;
  columnWidths: number[] = [];
  Extranet_Hotel_Id;
  Clone_Room_view;
  Allocationcols;
  AllocationResult;
  timer;
  cols;
  BlockDateResult;
  BlockDateCols;
  OverViewDetail;
  OverViewObj: OverViewData;
  Clone_Room_data;
  CloneRoomModal = false;
  displayPosition = false;
  AllRooms;
  MealsResult;
  RoomCol;
  MinStayResult;
  Contract_Results;
  OffersResult;
  OfferCols;
  SupplementResult;
  SupplementCols;
  SeasonCols;
  ContractCols;
  MealCols;
  Hotel_Details;
  MinDate = new Date();
  OverviewForm: FormGroup;
  constructor(
    public activateRoute: ActivatedRoute,
    public apiserv: API,
    public _commonService: CommonFunctionService,
    public router: Router,
    private fb: FormBuilder,
    public validserv: ValidationService) { }

  ngOnInit(): void {
    this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string;
    //room data
    this.RoomCol = [
      { field: 'room_name', header: 'Room Name' },
      { field: 'room_view', header: 'Room View' },
      { field: "max_adult_occupancy", header: 'Max Adult Occupancy' },
      { field: 'max_child_occupancy', header: 'Max Child Occupancy' },
      { field: 'max_child_age', header: 'Max Child Age' },
      { field: 'max_total_occupancy', header: 'Max Total Occupancy' },
      { field: 'is_extra_bed_supported', header: 'Extrabed Supported' },
      { field: 'is_free_child', header: 'Free Child Allowed' },
      { field: 'extranet_room_id', header: 'Room Id' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    //season data 
    this.SeasonCols = [
      { field: 'season_name', header: 'Season Name' },
      { field: 'date_range', header: 'Date Range' },
      { field: 'extranet_season_id', header: 'Season Id' },
      { field: 'updated_by', header: 'Created By' },
      { field: 'Custom_updated_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
      { field: 'status', header: 'Status' },
    ];
    //Contract data
    this.ContractCols = [
      { field: 'extranet_contract_id', header: 'Contract Id' },
      { field: 'contract_name', header: 'Contract Name' },
      { field: 'extranet_room_id', header: 'Room Id' },
      { field: 'room_name', header: 'Room Name' },
      { field: 'rate_plan_name', header: 'Rate Plan' },
      { field: 'meal_plan_name', header: 'Meal Plan' },
      { field: 'nationality_type', header: 'Nationality Type' },
      { field: 'nationality_applicable_type', header: 'Nationality Applicability' },
      { field: 'nationality', header: 'Nationality' },
      { field: 'date_range', header: 'Date Range/Season' },
      { field: 'currency_code', header: 'Currency' },
      { field: 'is_meal_addon_applicable', header: 'Meal Add On' },
      { field: 'addon_name', header: 'Meals' },
      { field: 'status', header: 'Contract Status' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
      { field: 'last_updated', header: 'Last Updated' },
    ];
    //Allocation Data
    this.Allocationcols = [
      { field: 'extranet_room_id', header: 'Room Id' },
      { field: 'room_name', header: 'Room Name' },
      { field: 'updated_by', header: 'Created By' },
      { field: 'Custom_updated_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    //Offers data
    this.OfferCols = [
      { field: 'offer_name', header: 'Offer Name' },
      { field: 'offer_type', header: 'Offer Type' },
      { field: 'room_name', header: 'Room Name' },
      { field: 'is_combinable_offer', header: 'Combinable Offer' },
      { field: 'discount_code', header: 'Discount Code' },
      { field: 'offer_days', header: 'Offer days' },
      { field: 'status', header: 'Status' },
      { field: 'extranet_offer_id', header: 'Offer Id' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    //Supplement data
    this.SupplementCols = [
      { field: 'supplement_name', header: 'Supplement Name' },
      { field: 'supplement_rate_type', header: 'Supplement Rate Type' },
      { field: 'room_name', header: 'Room Name' },
      { field: 'supplement_type', header: 'Supplement Type' },
      { field: 'date_range_arr', header: 'supplement_dates' },
      { field: 'custom_days', header: 'Supplement days' },
      { field: 'extranet_supplement_id', header: 'Supplement Id' },
      { field: 'status', header: 'Status' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' }
    ];
    //Meals data
    this.MealCols = [
      { field: 'addon_name', header: 'Meal Add-On Name' },
      { field: 'meal_plan_name', header: 'Meal Plan' },
      { field: 'currency', header: 'Currency' },
      { field: 'adult_rate', header: 'Adult Rate' },
      { field: 'currency', header: 'Currency' },
      { field: 'is_paid_child', header: 'Paid Child' },
      { field: 'status', header: 'Status' },
      { field: 'extranet_meal_addon_id', header: 'Meal Add-On Id' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    //Block Dates Data
    this.BlockDateCols = [
      { field: 'rule_name', header: 'Rule Name' },
      { field: 'block_date_type', header: 'Block Date Type' },
      { field: 'Custom_from_date', header: 'Date From' },
      { field: 'Custom_to_date', header: 'Date To' },
      { field: 'status', header: 'status' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_created_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    //Minimum Stay Data
    this.cols = [
      { field: 'extranet_room_id', header: 'Room Id' },
      { field: 'room_name', header: 'Room Name' },
      { field: 'date_range_arr', header: 'Minimum Stay Date Range' },
      { field: 'created_by', header: 'Created By' },
      { field: 'Custom_updated_on', header: 'Created On' },
      { field: 'updated_by', header: 'Updated By' },
      { field: 'Custom_updated_on', header: 'Updated On' },
    ];
    this.Initform();
    this.GetAllData();
  }
  GetAllData() {
    forkJoin(
      this.GetAllRooms(),
      this.GetHotelDetails(this.Extranet_Hotel_Id),
      this.SearchSeason(),
      this.SearchContract(),
      this.SearchAllocation(),
      this.SearchOffers(),
      this.SearchSupplement(),
      this.SearchMeals(),
      this.SearchBlockDate(),
      this.SearchMinStay(),
      this.GetOverViewData(),
    ).subscribe(res => {
      if (res && res.length > 0) {
        // Rooms Data
        this.AllRooms = res[0].data;
        if (res[0]) {
          this.AllRooms = res[0].data ? res[0].data : [];
          if (res[0].data) {
            this.AllRooms.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['is_extra_bed_supported'] = e.is_extra_bed_supported ? 'Yes' : 'No';
              e['is_free_child'] = e.is_free_child ? 'Yes' : 'No';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            });
            this.AllRooms.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }
        // Hotel Data
        this.Hotel_Details = res[1].data;
        if (this.Hotel_Details) {
          this.Hotel_Details['thumbnail_image'] = this.Hotel_Details['thumbnail_image'] ? JSON.parse(this.Hotel_Details['thumbnail_image']) : '';
        }

        //Season data
        if (res[2]) {
          this.SeasonResult = res[2].data ? res[2].data : [];
          if (res[2].data) {
            this.SeasonResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
              e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range'];
              if (typeof (e['date_range_arr']) != 'string') {
                e.date_range_arr.forEach((data, ind) => {
                  e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY');
                })
              }
            });
            this.SeasonResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }
        //contract data
        if (res[3]) {
          this.Contract_Results = res[3].data ? res[3].data : [];
          if (res[3].data) {
            this.Contract_Results.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['nationality_type'] = this.getNationalityType(e['nationality_type']) ;
              e['nationality_applicable_type'] = this.getNationalityApplicabilityType(e['nationality_applicable_type']) ;
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
              e['date_range_arr'] = e['contract_dates'] ? JSON.parse(e['contract_dates']) : [];
              if (typeof (e['date_range_arr']) != 'string') {
                e.date_range_arr.forEach((data, ind) => {
                  e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY');
                })
              }
              e['date_range'] = e.date_range_arr.length > 0 ? e.date_range_arr.join(',') : '';
            });
            this.Contract_Results.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Allocation data
        if (res[4]) {
          this.AllocationResult = res[4].data ? res[4].data : [];
          if (res[4].data) {
            this.AllocationResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            });
            this.AllocationResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Offers Data
        if (res[5]) {
          this.OffersResult = res[5].data ? res[5].data : [];
          if (res[5].data) {
            this.OffersResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['offer_type'] = this.getOfferType(e['offer_type']);
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            });
            this.OffersResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Supplement Data
        if (res[6]) {
          this.SupplementResult = res[6].data ? res[6].data : [];
          if (res[6].data) {
            this.SupplementResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['supplement_rate_type'] = this.getSupplementRateType(e.supplement_rate_type);
              e['supplement_type'] = this.getSupplementType(e.supplement_type);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
              e['date_range_arr'] = e['supplement_dates'] ? JSON.parse(e['supplement_dates']) : e['supplement_dates'];
              if (typeof (e['date_range_arr']) != 'string') {
                e.date_range_arr.forEach((data, ind) => {
                  e.date_range_arr[ind] = moment(data.from).format('DD MMM YYYY') + ' - ' + moment(data.to).format('DD MMM YYYY');
                })
              }
              e['custom_days'] = e['supplement_days'] ? e['supplement_days'].split(',') : ''
            });
            this.SupplementResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Meals Data
        if (res[7]) {
          this.MealsResult = res[7].data ? res[7].data : [];
          if (res[7].data) {
            this.MealsResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            });
            this.MealsResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Block Date data
        if (res[8]) {
          this.BlockDateResult = res[8].data ? res[8].data : [];
          if (res[8].data) {
            this.BlockDateResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range'];
              if (typeof (e['date_range_arr']) != 'string') {
                e.date_range_arr.forEach((data, ind) => {
                  e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY');
                })
              }
              e['Custom_created_on'] = this._commonService.convertDateWithTimeToShow(e.created_on);
              e['block_date_type'] = e.block_date_type == 'CHECKINDATE' ? 'Check-in Date' : 'Check-out Date';
            });
            this.BlockDateResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //Minimum Stay
        if(res[9]){
          this.MinStayResult = res[9].data ? res[9].data : [];
          if(res[9].data){
            this.MinStayResult.forEach(e => {
              e['status'] = e.is_active ? 'Active' : 'Deactive';
              e['date_range_arr'] = e['date_ranges'] ? JSON.parse(e['date_ranges']) : [];
              if(typeof(e['date_range_arr']) != 'string'){
                e.date_range_arr.forEach((data,ind)=>{
                  e.date_range_arr[ind] =  moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY');
                })
              }
              e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
              e['Custom_created_on'] = e['created_on'] ?  this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            });
            this.MinStayResult.sort((a: any, b: any) => {
              // Sort by status: Active first, then Deactive
              if (a.status !== b.status) {
                  return a.status === 'Active' ? -1 : 1;
              }
      
              // If both are Active, sort by activeDate
              if (a.status === 'Active') {
                  return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
              }
      
              // If both are Deactive, sort by deactiveDate
              return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime();
            });
          }
        }

        //OverviewData
        if (res[10]) {
          this.OverViewDetail = res[10].data;
          this.GetSortedOverviewDetails(res[10].data);
        }
      }
    })
  }
  GetHotelDetails(Editid) {
    if (Editid)
      return this.apiserv.Get('/ExtranetOverview/GetHotelData/' + Editid)
    else
      return of(null)
  };
  Initform() {
    const startDate = new Date();
    const endDate = new Date(startDate);
    endDate.setDate(startDate.getDate() + 29)
    this.OverviewForm = this.fb.group({
      extranet_room_id: '',
      date: new FormControl([startDate, endDate], [Validators.required, this.dateValidation()])
    });
  }

  // date validation 
  public dateValidation(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
      if (control.value) {
        if (control.value.length <= 1 || control.value[1] == null) {
          return { 'todate': true };
        }
        if (control.value.length == 2) {
          const diffInTime = control.value[1].getTime() - control.value[0].getTime(); // Difference in milliseconds
          const diffInDays = diffInTime / (1000 * 3600 * 24);
          if (diffInDays >= 30) {
            return { 'range': true };
          }
        }
      }
      return null;
    };
  }

  // scroll tab on click of button 
  // ngAfterViewInit() {
  //   this.calculateColumnWidths();
  // }

  calculateColumnWidths(scroll_side) {
    const container = this.tableContainer.nativeElement;
    const columns = container.querySelectorAll('th');
    this.columnWidths = Array.from(columns).map((col: HTMLElement) => col.offsetWidth);
    if(scroll_side == 'right'){
      this.scrollTable(1);
    }else if(scroll_side == 'left'){
      this.scrollTable(-1);
    }
  }
  // GetAllContract(){
  //   let obj = {
  //     extranet_hotel_id:this.Extranet_Hotel_Id
  //   }
  //   return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOfferAndSupplementContracts',obj)
  // }


  // scrollLeft() {
  //   this.scrollTable(-1);
  // }

  // scrollRight() {
  //   this.scrollTable(1);
  // }

  scrollTable(direction: number) {
    const container = this.tableContainer.nativeElement;
    const currentScroll = container.scrollLeft;
    const columnIndex = this.findCurrentColumn(currentScroll);

    if (columnIndex !== -1) {
      const scrollAmount = this.columnWidths[columnIndex] * direction;
      container.scrollLeft += scrollAmount;
    }
  }

  findCurrentColumn(currentScroll: number): number {
    let accumulatedWidth = 0;
    for (let i = 0; i < this.columnWidths.length; i++) {
      accumulatedWidth += this.columnWidths[i];
      if (accumulatedWidth > currentScroll) {
        return i;
      }
    }
    return -1; // In case something goes wrong
  }
  //OverView Data
  GetOverViewData() {
    //  console.log(this.OverviewForm.getRawValue());
    let val = this.OverviewForm.getRawValue();
    let Obj = {
      extranet_hotel_id: this.Extranet_Hotel_Id,
      extranet_room_id: val.extranet_room_id ? val.extranet_room_id : '',
      from_date: val.date ? moment(val.date[0]).format('YYYY-MM-DD') : '',
      to_date: val.date ? moment(val.date[1]).format('YYYY-MM-DD') : ''
    }
    return this.apiserv.Post('/ExtranetOverview/GetOverView', Obj)
  }
  SearchOverview() {
    if (this.OverviewForm.status == "INVALID") {
      this.validserv.showValidationsMsg(this.OverviewForm);
      return;
    }
    this.GetOverViewData().subscribe(res => {
      if (res) {
        this.OverViewDetail = res.data;
        this.GetSortedOverviewDetails(this.OverViewDetail);
      }
    })
  }
  Reset(){
    if(this.OverviewForm.get('extranet_room_id').value){
      this.OverviewForm.get('extranet_room_id').setValue('');
      this.SearchOverview();
    }
  }

  GetSortedOverviewDetails(Overview_det) {
    this.OverViewObj = undefined;
    if (Overview_det) {
      this.OverViewObj = {
        Date: [],
        RoomDetails: []
      }
      // console.log(Overview_det)
      let Unique_Date = [...new Set(Overview_det.map(item => item.overview_date))];
      const Unique_room_id = [...new Set(Overview_det.map(item => item.extranet_room_id))];
      Unique_Date.map((date: any, i) => {
        Unique_Date[i] = new Date(date);
      })
      Unique_Date.sort((a: any, b: any) => a - b);
      if (Unique_Date.length > 0) {
        Unique_room_id.forEach((room_id: any, room_ind) => {
          let room_data = Overview_det.filter(e => { return e.extranet_room_id == room_id })
          const contract_names = [...new Set(room_data.map(item => item.contract_name))];
          // let room_data_list = 

          let overview_data = {
            room_name: room_data[0].room_name,
            room_id: room_data[0].extranet_room_id,
            currency_code: room_data[0].currency_code,
            status: [],
            allocation: [],
            allocation_id:[],
            net_sold: [],
            availability: [],
            RoomContractDetails: []
          }
          // unique date and 
          contract_names.forEach((contract_data: any, contract_ind) => {
            let contractDetails = {
              contract_name: '',
              aria_collapse: true,
              rate_plan: '',
              meal_plan: '',
              child_age_range_1: '',
              child_age_range_2: '',
              min_stay: [],
              ChildDataRange1: [],
              ChildDataRange2: [],
              AdultData: []
            }
            let contract_details = Overview_det.find(e => { return (e.extranet_room_id == room_id && e.contract_name == contract_data) })
            contractDetails.contract_name = contract_details.contract_name;
            contractDetails.rate_plan = contract_details.rate_plan_name ? contract_details.rate_plan_name : '';
            contractDetails.meal_plan = contract_details.meal_plan_name ? contract_details.meal_plan_name : '';
            contractDetails.child_age_range_1 = contract_details.child_age_range_1 ? contract_details.child_age_range_1 : '';
            contractDetails.child_age_range_2 = contract_details.child_age_range_2 ? contract_details.child_age_range_2 : '';
            for(let i=0;i<contract_details.max_adult_occupancy;i++){
              contractDetails.AdultData[i] = {value:[]};
            }
            if(contractDetails.child_age_range_1){
              for(let i=0;i<contract_details.max_child_occupancy;i++){
                contractDetails.ChildDataRange1[i] = {value:[]};
              }
            }
            if(contractDetails.child_age_range_2){
              for(let i=0;i<contract_details.max_child_occupancy;i++){
                contractDetails.ChildDataRange2[i] = {value:[]};
              }
            }
            // console.log(Unique_Date)
            Unique_Date.forEach((date_data: any,date_ind) => {
              let room_data_on_date = Overview_det.find(e => { return (e.extranet_room_id == room_id && date_data.getTime() == new Date(e.overview_date).getTime() && e.contract_name == contract_data) })
              if (room_ind == 0 && contract_ind == 0) this.OverViewObj.Date.push(date_data);
              if(contract_ind == 0){
                let allocation_obj = {
                  id:`room${room_id}_allocation_${date_ind}`,
                  value:room_data_on_date ? room_data_on_date.allocation : ''
                }
                let available = room_data_on_date?.status == 'FREESALE' ? 'FREESALE' : room_data_on_date?.available;
                overview_data.status.push(room_data_on_date ? room_data_on_date.status : '');
                overview_data.allocation.push(allocation_obj);
                overview_data.allocation_id.push(room_data_on_date ? room_data_on_date.extranet_allocation_id : '');
                overview_data.availability.push(room_data_on_date ? available : '');
                overview_data.net_sold.push(room_data_on_date ? room_data_on_date.net_sold : '');
              }else if(room_data_on_date){
                let allocation_obj = {
                  id:`room${room_id}_allocation_${date_ind}`,
                  value:room_data_on_date ? room_data_on_date.allocation : ''
                }
                let available = room_data_on_date?.status == 'FREESALE' ? 'FREESALE' : room_data_on_date?.available;
                overview_data.status[date_ind] = room_data_on_date ? room_data_on_date.status : '';
                overview_data.allocation[date_ind] = allocation_obj;
                overview_data.allocation_id[date_ind] = room_data_on_date ? room_data_on_date.extranet_allocation_id : '';
                overview_data.availability[date_ind] = room_data_on_date ? available : '';
                overview_data.net_sold[date_ind] = room_data_on_date ? room_data_on_date.net_sold : '';
              }
              contractDetails.min_stay.push(room_data_on_date ? room_data_on_date.min_stay : '');
              for(let i=0;i<contract_details.max_adult_occupancy;i++){
                contractDetails.AdultData[i].value.push(room_data_on_date ? room_data_on_date[`adult_${i+1}`]:'');
              }
              if(contractDetails.child_age_range_1){
                for(let i=0;i<contract_details.max_child_occupancy;i++){
                  contractDetails.ChildDataRange1[i].value.push(room_data_on_date ? room_data_on_date[`age_range1_child_${i+1}`] :'');
                }
              }
              if(contractDetails.child_age_range_2){
                for(let i=0;i<contract_details.max_child_occupancy;i++){
                  contractDetails.ChildDataRange2[i].value.push(room_data_on_date ? room_data_on_date[`age_range2_child_${i+1}`] :'');
                }
              }
            })
            overview_data.RoomContractDetails.push(contractDetails);
          })

          this.OverViewObj.RoomDetails.push(overview_data);
        });
        console.log(this.OverViewObj)
      }
    }
  }
  CollapseContract(room_ind,contract_ind){
    this.OverViewObj.RoomDetails[room_ind].RoomContractDetails[contract_ind].aria_collapse = !this.OverViewObj.RoomDetails[room_ind].RoomContractDetails[contract_ind].aria_collapse;
  }
  //change status or allocation on a specific date 
  Update_Status(room_ind,data_ind,change_type,event){
    let room_data = this.OverViewObj.RoomDetails[room_ind];
    if(change_type == 'status'){
      this.OverViewObj.RoomDetails[room_ind][change_type][data_ind] = event;
    }else if(change_type == 'allocation'){
      const inputElement = event.target as HTMLInputElement;
      if(inputElement.valueAsNumber || inputElement.valueAsNumber === 0){
        this.OverViewObj.RoomDetails[room_ind][change_type][data_ind].value = inputElement.valueAsNumber;
      }else {
        this._commonService.showMessage(false,'allocation cannot be null')
        return
      }
    }
      clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        if((room_data.allocation[data_ind].value >= room_data.net_sold[data_ind] && (room_data.allocation[data_ind].value || room_data.allocation[data_ind].value === 0 )) || room_data.allocation[data_ind].value == 'FREESALE'){
        
        let Obj = {
          extranet_allocation_id:room_data.allocation_id[data_ind],
          status:room_data.status[data_ind],
          allocation:room_data.allocation[data_ind].value != 'FREESALE' ? parseInt(room_data.allocation[data_ind].value) : room_data.net_sold[data_ind],
          net_sold:room_data.net_sold[data_ind],
        }
        this.apiserv.Post('/ExtranetOverview/UpdateOverViewAllocationTypeAndLimit',Obj).subscribe(resp=>{
          if(resp){
            this._commonService.showMessage(resp.status,resp.message);
            if(resp.data){
              this.OverViewObj.RoomDetails[room_ind].availability[data_ind] = resp.data.status != 'FREESALE' ? resp.data.remaining_count : 'FREESALE';
              this.OverViewObj.RoomDetails[room_ind].allocation[data_ind].value = resp.data.status != 'FREESALE' ? parseInt(resp.data.allocation) : 'FREESALE';
            }
          }
        })
      }else {
        this._commonService.showMessage(false,'allocation cannot be lesser than net sold')
      }
      }, 500);
  }
  //

  // Rooms Data and functions

  GetAllRooms() {
    let ReObj = {
      is_free_child: '',
      is_extra_bed_supported: '',
      extranet_room_view_id: '',
      room_name: '',
      hotel_id: this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetHotelRoom/GetAllExtranetHotelRoom', ReObj)
  }
  CloneRoom(Id){
    this.router.navigateByUrl(`Services/Hotel/HotelManage/CloneRoom/${this.Extranet_Hotel_Id}/${Id}`);
  }
  updateRoomStatus(id, val) {
    let obj = {
      Id: id,
      Status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetHotelRoom/UpdateExtranetHotelRoomStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.SerachRooms() : '';
      }
    });
  }
  SerachRooms() {
    this.GetAllRooms().subscribe(res => {
      this.AllRooms = res.data;
      if (res) {
        this.AllRooms = res.data ? res.data : [];
        if (res.data) {
          this.AllRooms.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['is_extra_bed_supported'] = e.is_extra_bed_supported ? 'Yes' : 'No';
            e['is_free_child'] = e.is_free_child ? 'Yes' : 'No';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
          })
        }
      }
    })
  }
  EditRoom(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditRoom/${this.Extranet_Hotel_Id}/${Id}`);
  }
  //room Data Ends


  // Season Data
  SearchSeason() {
    let ReqObj = {
      season_name: '',
      hotel_id: this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason', ReqObj)
  }
  updateSeasonStatus(id, val) {
    let obj = {
      Id: id,
      status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetSeason/UpdateExtranetSeasonStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllSeason() : '';
      }
    });
  }

  EditSeason(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSeason/${this.Extranet_Hotel_Id}/${Id}`);
  }
  GetAllSeason() {
    this.SearchSeason().subscribe(res => {
      if (res) {
        this.SeasonResult = res.data ? res.data : [];
        if (res.data) {
          this.SeasonResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range'];
            if (typeof (e['date_range_arr']) != 'string') {
              e.date_range_arr.forEach((data, ind) => {
                e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY');
              })
            }
          })
        }
      }
    })
  }
  //Season data ends

  //Contract Data
  updateContractStatus(id, val) {
    let obj = {
      Id: id,
      Status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetRoomContractStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetallContract() : '';
      }
    });
  }
  SearchContract() {
    let ReObj = {
      extranet_hotel_id: this.Extranet_Hotel_Id,
      extranet_room_id: '',
      extranet_rate_plan_id: '',
      extranet_meal_plan_id: ''
    }
    return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetRoomContract', ReObj)
  }
  Update(Id, pagename) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/${pagename}/${this.Extranet_Hotel_Id}/${Id}`);
  }
  GetallContract() {
    this.SearchContract().subscribe(res => {
      if (res) {
        this.Contract_Results = res.data ? res.data : [];
        if (res.data) {
          this.Contract_Results.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['nationality_type'] = this.getNationalityType(e['nationality_type']) ;
            e['nationality_applicable_type'] = this.getNationalityApplicabilityType(e['nationality_applicable_type']) ;
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            e['date_range_arr'] = e['contract_dates'] ? JSON.parse(e['contract_dates']) : [];
            if (typeof (e['date_range_arr']) != 'string') {
              e.date_range_arr.forEach((data, ind) => {
                e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY');
              })
            }
            e['date_range'] = e.date_range_arr.length > 0 ? e.date_range_arr.join(',') : '';
          })
        }
      }
    })
  }
  EditContract(Id){
    this.router.navigateByUrl(`Services/Hotel/HotelManage/RoomContractEdit/${this.Extranet_Hotel_Id}/${Id}`);
  }
  getNationalityType(value){
    if(value == 'INCLUDE'){
      return 'Include'
    }else if(value == 'EXCLUDE'){
      return 'Exclude'
    }
    return ''
  }
  getNationalityApplicabilityType(value){
    if(value == 'ALL'){
      return 'All'
    }else if(value == 'SPECIFIC'){
      return 'Specific'
    }
    return ''
  }
  //contract data ends

  //Allocation data
  updateAllocationStatus(id, val) {
    let obj = {
      Id: id,
      status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetAllocation/UpdateExtranetAllocationStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllocationDeata() : '';
      }
    });
  }

  SearchAllocation() {
    let ReqObj = {
      extranet_room_id: '',
      extranet_hotel_id: this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetAllocation/GetAllExtranetAllocation', ReqObj)
  }
  GetAllocationDeata() {
    this.SearchAllocation().subscribe(res => {
      if (res) {
        this.AllocationResult = res.data ? res.data : [];
        if (res.data) {
          this.AllocationResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
          })
        }
      }
    })
  }

  EditAllocation(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/UpdateAllocation/${this.Extranet_Hotel_Id}/${Id}`);
  }
  //Allocation data ends

  //Offers data

  SearchOffers() {
    let obj = {
      extranet_hotel_id: this.Extranet_Hotel_Id,
      extranet_room_id: '',
      contract_name: '',
      offer_name: '',
      offer_type: '',
      discount_code: '',
      is_combinable_offer: '',
    }
    return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOffer', obj)
  }
  GetAllOffers() {
    this.SearchOffers().subscribe(res => {
      if (res) {
        this.OffersResult = res.data ? res.data : [];
        if (res.data) {
          this.OffersResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['offer_type'] = this.getOfferType(e['offer_type']);
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
          })
        }
      }
    })
  }
  updateOfferStatus(id, val) {
    let obj = {
      Id: id,
      status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetOffer/UpdateExtranetOfferStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllOffers() : '';
      }
    });
  }

  EditOffer(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/EditOffer/${this.Extranet_Hotel_Id}/${Id}`);
  }
  getOfferType(value){
    if(value == 'EARLYBIRD'){
      return 'Early Bird'
    }else if(value == 'STAYPAY'){
      return 'Stay Pay'
    }else if(value == 'LONGSTAY'){
      return 'Long Stay'
    }else if(value == 'DISCOUNT'){
      return 'Discount'
    }else if(value == 'CONTRACTREMARK'){
      return 'Contract Remark'
    }
    return ''
  }
  //Offer data ends

  //supplements data
  SearchSupplement() {
    let obj = {
      extranet_hotel_id: this.Extranet_Hotel_Id,
      extranet_room_id: '',
      contract_name: '',
      supplement_name: '',
      supplement_rate_type: '',
      supplement_type: '',
    }
    return this.apiserv.Post('/ExtranetSupplement/GetAllExtranetSupplement', obj)
  }
  GetAllSupplement() {
    this.SearchSupplement().subscribe(res => {
      if (res) {
        this.SupplementResult = res.data ? res.data : [];
        if (res.data) {
          this.SupplementResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['supplement_rate_type'] = this.getSupplementRateType(e.supplement_rate_type);
            e['supplement_type'] = this.getSupplementType(e.supplement_type);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
            e['date_range_arr'] = e['supplement_dates'] ? JSON.parse(e['supplement_dates']) : e['supplement_dates'];
            if (typeof (e['date_range_arr']) != 'string') {
              e.date_range_arr.forEach((data, ind) => {
                e.date_range_arr[ind] = moment(data.from).format('DD MMM YYYY') + ' - ' + moment(data.to).format('DD MMM YYYY');
              })
            }
            e['custom_days'] = e['supplement_days'] ? e['supplement_days'].split(',') : ''
          })
        }
      }
    })
  }
  updateSupplementStatus(id, val) {
    let obj = {
      Id: id,
      status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetSupplement/UpdateExtranetSupplementStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllSupplement() : '';
      }
    });
  }

  EditSupplement(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSuppliment/${this.Extranet_Hotel_Id}/${Id}`);
  }
  getSupplementType(value){
    if(value == 'ADDONRATE'){
      return 'Add-On Rate'
    }else if(value == 'NEWRATE'){
      return 'New Rate'
    }
    return ''
  }
  getSupplementRateType(value){
    if(value == 'PERROOMPERNIGHT'){
      return 'Per Room Per Night'
    }else if(value == 'PERPAXPERNIGHT'){
      return 'Per Pax Per Night'
    }else if(value == 'PERPAXPERSTAY'){
      return 'Per Pax Per Stay'
    }
    return ''
  }
  //Supplement Data ends

  //Meals Add-on data
  SearchMeals() {
    let ReObj = {
      addon_name: '',
      extranet_meal_plan_id: '',
      hotel_id: this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetMealAddon/GetAllExtranetMealAddon', ReObj)
  }
  GetAllMeals() {
    this.SearchMeals().subscribe(res => {
      if (res) {
        this.MealsResult = res.data ? res.data : [];
        if (res.data) {
          this.MealsResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on'];
          })
        }
      }
    })
  }
  updateMealsStatus(id, val) {
    let obj = {
      Id: id,
      Status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetMealAddon/UpdateExtranetMealAddOnStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllMeals() : '';
      }
    });
  }
  EditMeals(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelMealEdit/${this.Extranet_Hotel_Id}/${Id}`);
  }
  //Meals Data ends

  //Block Date Data 
  SearchBlockDate() {
    let ReqObj = {
      rule_name: '',
      block_date_type: '',
      hotel_id: this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetBlockDate/GetAllExtranetBlockDate', ReqObj)
  }
  GetAllBlockDate() {
    this.SearchBlockDate().subscribe(res => {
      if (res) {
        this.BlockDateResult = res.data ? res.data : [];
        if (res.data) {
          this.BlockDateResult.forEach(e => {
            e['status'] = e.is_active ? 'Active' : 'Deactive';
            e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on);
            e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range'];
            if (typeof (e['date_range_arr']) != 'string') {
              e.date_range_arr.forEach((data, ind) => {
                e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY');
              })
            }
            e['Custom_created_on'] = this._commonService.convertDateWithTimeToShow(e.created_on);
            e['block_date_type'] = e.block_date_type == 'CHECKINDATE' ? 'Check-in Date' : 'Check-out Date';
          })
        }
      }
    })
  }
  updateStatus(id, val) {
    let obj = {
      Id: id,
      status: val ? false : true,
    };
    this.apiserv.Post('/ExtranetBlockDate/UpdateExtranetBlockDateStatus', obj).subscribe(res => {
      if (res) {
        this._commonService.showMessage(res['status'], res['message']);
        res['status'] ? this.GetAllBlockDate() : '';
      }
    });
  }

  Edit(Id) {
    this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditBlockDate/${this.Extranet_Hotel_Id}/${Id}`);
  }
  //Block Date Data Ends

  //Minimum stay 
  SearchMinStay(){
    let ReqObj = {
      extranet_room_id:'',
      extranet_hotel_id:this.Extranet_Hotel_Id
    }
    return this.apiserv.Post('/ExtranetMinStay/GetAllExtranetRoomMinStay',ReqObj)
  }

  EditMinStay(Id){
  this.router.navigateByUrl(`Services/Hotel/HotelManage/EditMinStay/${this.Extranet_Hotel_Id}/${Id}`);
  }
  //Minimum Stay ends 

}
