import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { API } from 'src/app/core/services/api.service';
import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns';
import { ValidationService } from 'src/app/core/common/validation.service';
import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import * as moment from 'moment';
import { CommonFunctionService } from 'src/app/core/common/common-function.service';
import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service';

@Component({
  selector: 'hotel-update-cancellation',
  templateUrl: './hotel-update-cancellation.component.html',
})
export class HotelUpdateCancellationComponent implements OnInit {
  Extranet_Hotel_Id;
  Edit_Id;
  Range_Data;
  AllSeason;
  Defaultdate = new Date();
  GetAllContractResp;
  GetAllData;
  Validation_Message_Obj = [];
  cancellation_array_length;
  selectedDate: Date | null = null;
  DisableDate;
  selectAll = ['Select All'];
  hasResult = false;
  enabledDates: Date[] = [];
  AllDaysArr = [
    {Key:'Mon',Value:'Monday'},
    {Key:'Tue',Value:'Tuesday'},
    {Key:'Wed',Value:'Wednesday'},
    {Key:'Thu',Value:'Thursday'},
    {Key:'Fri',Value:'Friday'},
    {Key:'Sat',Value:'Saturday'},
    {Key:'Sun',Value:'Sunday'}
  ];
  Cancellation_contract_Search_Form:FormGroup;
  Cancellation_contract_Save_Form:FormGroup;

  constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService,
    private hotelmanageserv:ManageHotelService,private router:Router) { }

  ngOnInit(): void {
    this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string;
    this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string;
    this.Cancellation_contract_Search_Form = this.fb.group({
      room_Name:'',
      rate_Plan:'',
      meal_Plan:'',
      currency:'',
      date_type:this.validserv.required,
      contract_days:''
    })
    this.GetAllSeason();
    this.GetById();
    // this.disabledDates();
  }

  GetById(){
    this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{
      if(res && res.data){
        // this.SetRoomdata(res.data);
        let dates_range_arr = res.data['contract_dates'] ? JSON.parse(res.data.contract_dates) : [];
        this.Cancellation_contract_Search_Form.get('room_Name').setValue(res.data.room_name);
        this.Cancellation_contract_Search_Form.get('rate_Plan').setValue(res.data.rate_plan_name);
        this.Cancellation_contract_Search_Form.get('meal_Plan').setValue(res.data.meal_plan_name);
        this.Cancellation_contract_Search_Form.get('currency').setValue(res.data.currency_code);
        this.GetAllData = res.data;
        this.Range_Data = res.data.age_range ? JSON.parse(res.data.age_range) : [];
        // this.GetAllData['max_adult_occupancy'] = 3;
        dates_range_arr.forEach(date_range=>{
          const startDate = parseISO(date_range.date_from);
          const endDate = parseISO(date_range.date_to);

          for (let d = startDate; d <= endDate; d = addDays(d, 1)) {
            this.enabledDates.push(d);
          }
        });
        this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime());
        for(let i=0;i<this.enabledDates.length;i++){
          if(new Date(this.enabledDates[i]).getTime() >= new Date().getTime()){
            this.Defaultdate = new Date(this.enabledDates[i]);
            break;
          }
          if(this.enabledDates.length -1 == i){
            this.Defaultdate = new Date(this.enabledDates[i]);
          }
        }
        let to_date = new Date(this.enabledDates[0]);
        to_date.setMonth(to_date.getMonth()-12)
        let from_date = new Date(this.enabledDates[0]);
        from_date.setMonth(from_date.getMonth() + 18)
        this.DisableDate = this.disabledDates(to_date,from_date)
      }
    })
  }
  disabledDates(to_date,From_date): Date[] {
    const start = startOfYear(new Date(to_date));
    const end = endOfYear(new Date(From_date));
    const disabledDates: Date[] = [];

    for (let d = start; d <= end; d.setDate(d.getDate() + 1)) {
      if (!this.isDateEnabled(new Date(d))) {
        disabledDates.push(new Date(d));
      }
    }
    
    return disabledDates;
  }

  isDateEnabled(date: Date): boolean {
    return this.enabledDates.some(enabledDate => 
      isSameDay(date, enabledDate)
    );
  }
  BackButton(){
    this.hotelmanageserv.Active_tab = 'RoomContract';
    this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`);
  }
  Check_day_type(){
    let daysArr = [
      'Monday',
      'Tuesday',
      'Wednesday',
      'Thursday',
      'Friday',
      'Saturday',
      'Sunday'
    ];
    let value = this.Cancellation_contract_Search_Form.get('contract_days').value;
    if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){
      this.Cancellation_contract_Search_Form.get('contract_days').setValue(daysArr);
      this.selectAll = []
    }else {
      this.selectAll = ['Select All']
    }
  }
  Reset(){
    this.Cancellation_contract_Search_Form.reset()
  }

  SearchCancellationcontract(){
    if (this.Cancellation_contract_Search_Form.status == "INVALID") {
      this.validserv.showValidationsMsg(this.Cancellation_contract_Search_Form);
      setTimeout(() => {
        this.validserv.scrollToError();
      }, 50);
      return;
    }
    let val = this.Cancellation_contract_Search_Form.getRawValue();
    let ReqObj = {
      extranet_contract_id:this.Edit_Id,
      date_range:[],
      contract_days:val.contract_days ? val.contract_days.join(','):'',
    }
    if(val.date_type == 'SPECIFICDATES'){
      const selectedFromDate = new Date(val.date[0]);
      const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds
      const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset);
      const selectedToDate = new Date(val.date[1]);
      const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds
      const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset);
      ReqObj.date_range.push({
        date_from:fromDate,
        date_to:toDate,
      });
    }else if(val.date_type == 'SEASON'){
      val.Season_Id.forEach(data => {
        let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data);
        if (matched_season_by_id) {
          if (typeof (matched_season_by_id['date_range']) == 'string') {
            let splited_date = matched_season_by_id.date_range.split(', ');
            splited_date.forEach((z) => {
              ReqObj.date_range.push({
                date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`),
                date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`),
              });
            })
          }
        }
      })
    }
    this.apiserv.Post('/ExtranetRoomContract/GetAllCancellationPolicy',ReqObj).subscribe(resp=>{
      this.hasResult = true;
      if(resp){
        this.Cancellation_contract_Save_Form = this.fb.group({
          Cancellation_Contract_Arr:this.fb.array([])
        });
        if(resp.data){
          this.GetAllContractResp = resp.data;
          resp.data.sort((a,b)=>{
            let from_date = new Date(a.contract_date);
            let to_date = new Date(b.contract_date)
            return from_date.getTime() - to_date.getTime() 
          });
          let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray;
          resp.data.forEach((contract_data,contract_ind)=>{
            let day  = this.AllDaysArr.find(e=>e.Value == contract_data.contract_day);
            if(contract_ind == 0 || contract_data.contract_date != resp.data[contract_ind -1 ]['contract_date']){
              contract_Arr.push(
                this.fb.group({
                  Cancel_Array: this.fb.array([])
                })
              );
              this.Validation_Message_Obj.push({
                cancel_type_select:false,
                cancel_from_enter:false,
                cancel_from_range:false,
                cancel_to_enter:false,
                cancel_to_range:false,
                night_type_select:false,
                charge_value_enter:false,
              })
            }
            let formGroup = contract_Arr.controls[contract_Arr.controls.length - 1]['controls']['Cancel_Array'] as FormArray
            formGroup.push(this.fb.group({
              cancel_from: [contract_data.cancel_from,Validators.compose([Validators.required])],
              cancel_to: [contract_data.cancel_to,Validators.compose([Validators.required])],
              cancellation_type: [contract_data.cancellation_type,Validators.compose([Validators.required])],
              contract_date:contract_data.contract_date,
              contract_day:day ? day.Key : '',
              extranet_cancellation_policy_id:contract_data.extranet_cancellation_policy_id,
              contract_type:contract_data.contract_type,
              // charge_value:contract_data.charge_value
            }));
            let formgroup = formGroup.controls[formGroup.length -1] as FormGroup;
            if(contract_data.cancellation_type != 'FULLCHARGES'){
              formgroup.addControl(`charge_value`,this.fb.control(contract_data.charge_value, [Validators.required]));
            }
            if(contract_data.cancellation_type == 'NIGHTCOUNT'){
              formgroup.addControl(`night_type`,this.fb.control(contract_data.night_type, [Validators.required]));
            }
            if(contract_ind != 0 && contract_data.contract_date == resp.data[contract_ind -1 ]['contract_date']){
              formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')])
              formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')])
            }
          });
        }else {
          this.GetAllContractResp = undefined;
          this.commonMasterSer.showMessage(resp.status,resp.message);
        }
      }
    })
  }
  private AmountRangeValidation(initialValue): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
      if (control.value || control.value == 0) {
        if (initialValue && parseInt(control.value) <= parseInt(initialValue)) {
          return { 'range': true };
        }
      }
      return null;
    };
  }
  Checkcanceltype(event,i,j){
    let formcontrol = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j] as FormGroup;
    if(event == 'NIGHTCOUNT'){
      formcontrol.addControl('night_type',new FormControl('',Validators.required));
      formcontrol.addControl('charge_value',new FormControl(0,Validators.required));
    } else if(event == 'FULLCHARGES'){
      formcontrol.removeControl('charge_value');
      formcontrol.removeControl('night_type');
    } else {
      if(!formcontrol.controls['charge_value']){
      formcontrol.addControl('charge_value',new FormControl(0,Validators.required));
      }
      formcontrol.removeControl('night_type');
    }
    this.Find_Validation(i)
  }
  Find_Validation(i){
    let formcontrol = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'];
    this.Validation_Message_Obj[i] = {
      cancel_type_select:false,
      cancel_from_enter:false,
      cancel_from_range:false,
      cancel_to_enter:false,
      cancel_to_range:false,
      night_type_select:false,
      charge_value_enter:false,
    }
    formcontrol.forEach(formgroup=>{
      if(formgroup.controls['cancellation_type'].hasError('required')){
        this.Validation_Message_Obj[i]['cancel_type_select'] = true;
      }
      if(formgroup.controls['cancel_from'].hasError('required')){
        this.Validation_Message_Obj[i]['cancel_from_enter'] = true;
      }
      if(formgroup.controls['cancel_from'].hasError('range')){
        this.Validation_Message_Obj[i]['cancel_from_range'] = true;
      }
      if(formgroup.controls['cancel_to'].hasError('required')){
        this.Validation_Message_Obj[i]['cancel_to_enter'] = true;
      }
      if(formgroup.controls['cancel_to'].hasError('range')){
        this.Validation_Message_Obj[i]['cancel_to_range'] = true;
      }
      if(formgroup.controls['night_type'] && formgroup.controls['night_type'].hasError('required')){
        this.Validation_Message_Obj[i]['night_type_select'] = true;
      }
      if(formgroup.controls['charge_value'] &&  formgroup.controls['charge_value'].hasError('required')){
        this.Validation_Message_Obj[i]['charge_value_enter'] = true;
      }
    })
  }
  ChangeFeeMinValue(controlname,min,i,j) {
    let min_amt = min;
    if(this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j]){
      this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).clearValidators();
      this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]);
      this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).markAsUntouched();
      this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).setErrors(null);
      this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).updateValueAndValidity();
      this.Find_Validation(i)
    }
  }
  Copy_first_Block_Ui(){
    let formarray = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'];
    let copy_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][0]['controls']['Cancel_Array']['controls'];
    formarray.forEach((fomrgroup,ind)=>{
      if(ind>0){
        fomrgroup.controls['Cancel_Array']['controls'].forEach((arr_data,arr_Ind)=>{
          let copy_group = copy_Arr[arr_Ind].getRawValue();
          arr_data.get('cancellation_type').setValue(copy_group.cancellation_type);
          arr_data.get('cancel_from').setValue(copy_group.cancel_from);
          arr_data.get('cancel_to').setValue(copy_group.cancel_to);
          if(copy_group.cancellation_type != 'FULLCHARGES'){
            if(arr_data.controls['charge_value']){
              arr_data.get('charge_value').setValue(copy_group.charge_value);
            }else{
              arr_data.addControl(`charge_value`,this.fb.control(copy_group.charge_value, [Validators.required]));
            }
          }else if(copy_group.cancellation_type == 'FULLCHARGES'){
            arr_data.removeControl('charge_value');
          }
          if(copy_group.cancellation_type == 'NIGHTCOUNT'){
            if(arr_data.controls['night_type']){
              arr_data.get('night_type').setValue(copy_group.night_type);
            }else{
              arr_data.addControl(`night_type`,this.fb.control(copy_group.night_type, [Validators.required]));
            }
          }else {
            arr_data.removeControl('night_type');
          }
          arr_data.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(fomrgroup.controls[arr_Ind -1 ]?parseInt(fomrgroup.controls[arr_Ind -1].get('cancel_to').value):'')])
          arr_data.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(arr_data?parseInt(arr_data.get('cancel_from').value):'')])
        })
      }
    })
  }
  Save(){
    if (this.Cancellation_contract_Save_Form.status == "INVALID") {
      this.validserv.showValidationsMsg(this.Cancellation_contract_Save_Form);
      setTimeout(() => {
        this.validserv.scrollToError();
      }, 50);
      return;
    }
    let val = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'].getRawValue();
    let reqObjArr = [];
    val.forEach(cancellationcontract=>{
      cancellationcontract.Cancel_Array.forEach(cancellation_data=>{
        reqObjArr.push({
          extranet_cancellation_policy_id : cancellation_data.extranet_cancellation_policy_id,
          extranet_contract_id : this.Edit_Id,
          contract_date : cancellation_data.contract_date,
          contract_day : cancellation_data.contract_day,
          contract_type : cancellation_data.contract_type,
          cancel_from : cancellation_data.cancel_from,
          cancel_to : cancellation_data.cancel_to,
          cancellation_type : cancellation_data.cancellation_type,
        });
        if(cancellation_data.night_type)reqObjArr[reqObjArr.length - 1]['night_type'] = cancellation_data.night_type;
        if(cancellation_data.charge_value)reqObjArr[reqObjArr.length - 1]['charge_value'] = parseInt(cancellation_data.charge_value);
      })
    });
    this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetCancellationPolicy',reqObjArr).subscribe(resp=>{
      if(resp){
        this.commonMasterSer.showMessage(resp.status,resp.message);
        resp.status ? this.BackButton() : '';
      }
    })
  }
  AddCancellationArr(i,j){
    let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray;
    let formGroup = contract_Arr.controls[i]['controls']['Cancel_Array'] as FormArray
    formGroup.push(this.fb.group({
      cancel_from: ['',Validators.compose([Validators.required])],
      cancel_to: ['',Validators.compose([Validators.required])],
      cancellation_type: ['',Validators.compose([Validators.required])],
      contract_date:formGroup.controls[0].get('contract_date').value,
      contract_day:formGroup.controls[0].get('contract_day').value,
      extranet_cancellation_policy_id:'',
      contract_type:'',
      // charge_value:contract_data.charge_value
    }));
    let formgroup = formGroup.controls[formGroup.length -1] as FormGroup;
    // if(contract_data.cancellation_type != 'FULLCHARGES'){
    //   formgroup.addControl(`charge_value`,this.fb.control(contract_data.charge_value, [Validators.required]));
    // }
    // if(contract_data.cancellation_type == 'NIGHTCOUNT'){
    //   formgroup.addControl(`night_type`,this.fb.control(contract_data.night_type, [Validators.required]));
    // }
    if(formGroup.controls[j].get('cancel_from').value && formGroup.controls[j].get('cancel_to').value){
      formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')])
      formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')])
    }
  }
  RemoveCancellationArr(i,j){
    let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray;
    let formGroup = contract_Arr.controls[i]['controls']['Cancel_Array'] as FormArray;
    formGroup.removeAt(j);
    this.Find_Validation(i);
    let formgroup = formGroup.controls[j] as FormGroup;
    if(formGroup.controls[j-1]?.get('cancel_from').value && formGroup.controls[j-1]?.get('cancel_to').value || j==0){
      formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')])
      formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')])
      formgroup.updateValueAndValidity();
    }
  }

  ShowDateTypeFields(event){
    if(event == 'SPECIFICDATES'){
      this.Cancellation_contract_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()])));
      this.Cancellation_contract_Search_Form.removeControl('Season_Id');
    }else if(event == 'SEASON'){
      this.Cancellation_contract_Search_Form.addControl('Season_Id',new FormControl('',Validators.required))
      this.Cancellation_contract_Search_Form.removeControl('date');
    }else {
      this.Cancellation_contract_Search_Form.removeControl('Season_Id');
      this.Cancellation_contract_Search_Form.removeControl('date');
    }
  }
  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 };
        }
      }
      return null;
    };
  }

  GetAllSeason(){
    let ReqObj = {
      season_name:'',
      hotel_id:this.Extranet_Hotel_Id
    }
    this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{
      if(res){
        this.AllSeason = res.data;
      }
    })
  }
}
