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';
import { MessageService } from 'primeng/api';

@Component({
  selector: 'hotel-update-allocation',
  templateUrl: './hotel-update-allocation.component.html',
})
export class HotelUpdateAllocationComponent implements OnInit {
  Extranet_Hotel_Id;
  Edit_Id;
  Defaultdate = new Date();
  GetAllContractResp;
  GetAllData;
  AllSeason;
  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'}
  ];
  Allocation_Search_Form:FormGroup;
  Allocation_Save_Form:FormGroup;
  IsMobile;

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

  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.Allocation_Search_Form = this.fb.group({
      room_Name:'',
      room_Id:'',
      date_type:this.validserv.required,
      allocation_days:[]
    })
    this.GetAllSeason();
    this.GetById();
    // this.disabledDates();
  }

  GetById(){
    this.apiserv.Get('/ExtranetAllocation/GetExtranetAllocationById/'+ this.Edit_Id).subscribe(res=>{
      if(res && res.data){
        // this.SetRoomdata(res.data);
        let dates_range_arr = res.data['date_ranges'] ? JSON.parse(res.data.date_ranges) : [];
        this.Allocation_Search_Form.get('room_Name').setValue(res.data.room_name);
        this.Allocation_Search_Form.get('room_Id').setValue(res.data.extranet_room_id);
        this.GetAllData = res.data;
        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 = 'Allocation';
    this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`);
  }
  SearchAllocation(){
    if (this.Allocation_Search_Form.status == "INVALID") {
      this.validserv.showValidationsMsg(this.Allocation_Search_Form);
      setTimeout(() => {
        this.validserv.scrollToError();
      }, 50);
      return;
    }
    let val = this.Allocation_Search_Form.getRawValue();
    let ReqObj = {
      extranet_room_id:val.room_Id ? val.room_Id:'',
      extranet_hotel_id:this.Extranet_Hotel_Id,
      date_range:[],
      allocation_days:val.allocation_days ? val.allocation_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('/ExtranetAllocation/GetUpdateallocation',ReqObj).subscribe(resp=>{
      this.hasResult = true;
      if(resp){
        this.GetAllContractResp = resp.data && resp.data.length > 0 ? resp.data : undefined;
          this.Allocation_Save_Form = this.fb.group({
            Copy_Group:this.fb.group({
              allocation_type:'',
              allocation_limit:'',
              release_days:'',
            }),
            Allocation_Arr:this.fb.array([])
          });
       if(resp.data){
        resp.data.sort((a,b)=>{
          let from_date = new Date(a.allocation_date);
          let to_date = new Date(b.allocation_date)
          return from_date.getTime() - to_date.getTime() 
        })
        resp.data.forEach((contract_data,ind)=>{
          let formArray = this.Allocation_Save_Form.controls['Allocation_Arr'] as FormArray;
          let day  = this.AllDaysArr.find(e=>e.Value == contract_data.contract_day)
          formArray.push(this.fb.group({
            allocation_type:contract_data.allocation_type,
            allocation_limit:contract_data.allocation_limit,
            release_days:contract_data.release_days,
            allocation_date:contract_data.allocation_date,
            allocation_day:contract_data.allocation_day,
            booking_count:contract_data.booking_count,
            remaining_count:contract_data.remaining_count,
            contract_day:day ? day.Key : '',
            extranet_allocation_id:contract_data.extranet_allocation_id,
            extranet_room_id:contract_data.extranet_room_id,
            Is_Required:false
          }));

            let formgroup = formArray.controls[ind] as FormGroup;
            if(contract_data.booking_count || contract_data.allocation_limit || contract_data.release_days || contract_data.remaining_count){
              if(contract_data.allocation_type=='FREESALE' || contract_data.allocation_type=='STOPSALE'){
                formgroup.get('allocation_limit').disable();
                formgroup.get('release_days').disable();
              }else {
                formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(contract_data.booking_count )]);
                formgroup.get('release_days').addValidators([Validators.required]);
              }
              formgroup.get('allocation_type').addValidators([Validators.required]);
              formgroup.get('Is_Required').setValue(true);
            }
        })
       }else {
        this.commonMasterSer.showMessage(resp.status,resp.message);
       }
      }
    })
  };
  get copyForm(){
    return this.Allocation_Save_Form.get('Copy_Group') as FormGroup
  }
  copycolumn(colname,controlval?){
    let value = controlval ? controlval : this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][0].get(colname).value;
    if(this.GetAllContractResp && this.GetAllContractResp.length > 0){
      for(let i = 0;i<this.GetAllContractResp.length;i++){
        if( this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i].get('allocation_type').value != 'FREESALE' || colname == 'allocation_type'){
          this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i].get(colname).setValue(value);
        }
          if(colname == 'allocation_type'){
            this.AllocationType_Check(i)
          }
      }
    }
  }
  CopyOnUi(){
    let val = this.Allocation_Save_Form.controls['Copy_Group'].getRawValue();
    if(val.allocation_type){
      this.copycolumn('allocation_type',val.allocation_type);
    }
    if(val.allocation_limit){
      this.copycolumn('allocation_limit',val.allocation_limit);
    }
    if(val.release_days){
      this.copycolumn('release_days',val.release_days);
    }
   
  }
  Save(){
    let val = this.Allocation_Save_Form.controls['Allocation_Arr'].getRawValue();
    if (this.Allocation_Save_Form.status == "INVALID") {
      this.validserv.showValidationsMsg(this.Allocation_Save_Form);
      setTimeout(() => {
        this.validserv.scrollToError();
      }, 50);
      for(let i = 0;i<val.length;i++){
        this.checkvalidation(i);
      }
      return;
    }
    let reqObjArr = [];
    val.forEach(Allocationdata=>{
      reqObjArr.push({
        extranet_allocation_id : Allocationdata.extranet_allocation_id,
        extranet_room_id : Allocationdata.extranet_room_id,
        extranet_hotel_id : this.Extranet_Hotel_Id,
        allocation_date : Allocationdata.allocation_date,
        allocation_day : Allocationdata.allocation_day,
        allocation_type : Allocationdata.allocation_type,
        booking_count : Allocationdata.booking_count ? parseInt(Allocationdata.booking_count) :0,
        remaining_count : Allocationdata.remaining_count ? parseInt(Allocationdata.remaining_count) : 0,
        release_days : Allocationdata.release_days ? Allocationdata.release_days : '',
        allocation_limit : Allocationdata.allocation_limit ? Allocationdata.allocation_limit : ''
      })
    });
    this.apiserv.Post('/ExtranetAllocation/UpdateExtranetAllocation',reqObjArr).subscribe(resp=>{
      if(resp){
        this.commonMasterSer.showMessage(resp.status,resp.message);
        resp.status ? this.BackButton() : '';
      }
    })
  }
  Reset(){
    this.Allocation_Search_Form.reset();
  }
  Check_day_type(){
    let daysArr = [
      'Monday',
      'Tuesday',
      'Wednesday',
      'Thursday',
      'Friday',
      'Saturday',
      'Sunday'
    ];
    let value = this.Allocation_Search_Form.get('allocation_days').value;
    if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){
      this.Allocation_Search_Form.get('allocation_days').setValue(daysArr);
      this.selectAll = []
    }else {
      this.selectAll = ['Select All']
    }
  }
  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;
    };
  }
  AllocationType_Check(i){
    let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup;
    let val = formgroup.get('allocation_type').value;
    if(val == 'FREESALE'){
      formgroup.get('allocation_limit').disable();
      formgroup.get('release_days').disable();
      formgroup.get('allocation_limit').clearValidators();
      formgroup.get('release_days').clearValidators();
      formgroup.get('allocation_limit').setValue('FREESALE');
    }
    else if( val=='STOPSALE'){
      formgroup.get('allocation_limit').disable();
      formgroup.get('release_days').disable();
      formgroup.get('allocation_limit').clearValidators();
      formgroup.get('release_days').clearValidators();
    }else if(val == 'COUNTSALE') {
      formgroup.get('release_days').enable();
      formgroup.get('allocation_limit').enable();
      formgroup.get('allocation_limit').setValue(formgroup.get('allocation_limit').value == 'FREESALE' ? formgroup.get('booking_count').value : formgroup.get('allocation_limit').value);
      formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]);
      formgroup.get('release_days').addValidators([Validators.required]);
    }else if((!formgroup.get('Is_Required').value && (formgroup.get('allocation_limit').value || formgroup.get('release_days').value)) || formgroup.get('Is_Required').value){
      formgroup.get('release_days').enable();
      formgroup.get('allocation_limit').enable();
      formgroup.get('allocation_limit').setValue(formgroup.get('booking_count').value);
      formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]);
      formgroup.get('release_days').addValidators([Validators.required]);
      formgroup.get('allocation_type').addValidators([Validators.required]);
    }else {
      formgroup.get('release_days').enable();
      formgroup.get('allocation_limit').enable();
      formgroup.get('allocation_limit').setValue('');
      formgroup.get('release_days').setValue('');
      formgroup.get('allocation_limit').clearValidators();
      formgroup.get('release_days').clearValidators();
      formgroup.get('allocation_type').clearValidators();
    }
    // formgroup.get('allocation_type').addValidators([Validators.required]);
    // formgroup.get('Is_Required').setValue(true);
    formgroup.get('allocation_limit').updateValueAndValidity();
    formgroup.get('release_days').updateValueAndValidity();
    formgroup.get('allocation_type').updateValueAndValidity();
    this.checkvalidation(i);
  }
  checkvalidation(i){
    let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup;
    // if(formgroup.get('Is_Required').value || (!formgroup.get('Is_Required').value || formgroup.get('Is_Required').value)){
      if(formgroup.get('allocation_type').hasError('required')){
        this.messageService.add({
          severity: 'error',
          detail: 'Please select allocation type',
          sticky: true // Toast will remain visible until manually closed
        });
      }
      if(formgroup.get('allocation_limit').hasError('required')){
        this.messageService.add({
          severity: 'error',
          detail: 'Please enter allocation',
          sticky: true // Toast will remain visible until manually closed
        });
      }
      if(formgroup.get('allocation_limit').hasError('range')){
        this.messageService.add({
          severity: 'info',
          detail: 'Allocation can not be lesser than booking count',
          sticky: true // Toast will remain visible until manually closed
        });
      }
      if(formgroup.get('release_days').hasError('required')){
        this.messageService.add({
          severity: 'error',
          detail: 'Please enter release days',
          sticky: true // Toast will remain visible until manually closed
        });
      }
    // }
  }
  check_Allocation_and_Realase_Validation(i){
    let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup;
    if(!formgroup.get('Is_Required').value && (formgroup.get('allocation_type').value || formgroup.get('allocation_limit').value || formgroup.get('release_days').value)){
      formgroup.get('release_days').enable();
      formgroup.get('allocation_limit').enable();
      // formgroup.get('allocation_limit').setValue(formgroup.get('booking_count').value);
      formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]);
      formgroup.get('release_days').addValidators([Validators.required]);
      formgroup.get('allocation_type').addValidators([Validators.required]);
    }else if(!formgroup.get('Is_Required').value ){
      formgroup.get('allocation_limit').clearValidators();
      formgroup.get('release_days').clearValidators();
      formgroup.get('allocation_type').clearValidators();
    }
    formgroup.get('allocation_limit').updateValueAndValidity();
    formgroup.get('release_days').updateValueAndValidity();
    formgroup.get('allocation_type').updateValueAndValidity();
    this.checkvalidation(i);
  }
  Copy_Group_Type_check(event){
    if(event == 'FREESALE'){
      this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').setValue('FREESALE');
      this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').disable()
    }else {
      if(this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').value == 'FREESALE'){
        this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').setValue('');
      }
      this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').enable();
    }

  }

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