import {ChangeDetectorRef, Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms';
import {Page} from '../../utils/entities/adminTool/page';
import {HelpContentService} from '../../services/help-content.service';
import {EnvProperties} from '../../utils/properties/env-properties';
import {properties} from '../../../../environments/environment';
import {Subscriber, Subscription, zip} from 'rxjs';
import {HelperFunctions} from '../../utils/HelperFunctions.class';
import {PageHelpContent} from '../../utils/entities/adminTool/page-help-content';
import {ClearCacheService} from "../../services/clear-cache.service";
import {NotificationHandler} from "../../utils/notification-handler";
import {CKEditorComponent} from "ng2-ckeditor";

@Component({
  selector: 'page-content-form',
  templateUrl: './page-help-content-form.component.html',
})
export class PageContentFormComponent implements OnInit {
  
  myForm: UntypedFormGroup;
  portal: string;
  parentClass: string;
  pageId: string;
  pageContentId: string;
  page: Page;
  placementsOptions = [];
  orderOptions = [];
  public properties: EnvProperties = properties;
  public showLoading: boolean = true;
  private subs: Subscription[] = [];
  public pageHelpContent: PageHelpContent;
  @ViewChild('ckEditor') ckEditor: CKEditorComponent;

  constructor(private route: ActivatedRoute, private _router: Router, private _fb: UntypedFormBuilder,
              private cdr: ChangeDetectorRef, private _helpContentService: HelpContentService,
              private _clearCacheService: ClearCacheService) {
  }
  
  ngOnInit() {
    this.portal = (this.route.snapshot.data.portal) ? this.route.snapshot.data.portal : this.route.snapshot.params[this.route.snapshot.data.param];
    this.parentClass = this.route.snapshot.data.parentClass;
    this.subs.push(this.route.queryParams.subscribe(params => {
      HelperFunctions.scroll();
      this.pageId = params['pageId'];
      this.myForm = this.form;
      this.pageContentId = params['pageContentId'];
      if (!this.pageId) {
        this._router.navigate(['../'], {relativeTo: this.route});
      }
      this.getInfo(this.pageId);
    }));
  }
  
  ngOnDestroy() {
    this.subs.forEach(value => {
      if (value instanceof Subscriber) {
        value.unsubscribe();
      }
    });
  }
  
  getInfo(pageId: string) {
    this.showLoading = true;
    let obs = zip(this._helpContentService.getPageByPortal(pageId, this.properties.adminToolsAPIURL, this.portal), this._helpContentService.getCommunityPageHelpContents(this.portal, this.properties.adminToolsAPIURL, pageId));
    this.subs.push(obs.subscribe(
      results => {
        this.page = results[0];
        if (this.properties.adminToolsPortalType != this.page.portalType) {
          this._router.navigate(['../'], {relativeTo: this.route});
        }
        let countPageContents = results[1] ? results[1].length : 0;
        for (let content of (results[1] as Array<PageHelpContent>)) {
          if (this.pageContentId && this.pageContentId == content._id) {
            this.pageHelpContent = content;
          }
        }
        this.setOptions(this.page, countPageContents + (this.pageHelpContent ? 0 : 1));
        if (!this.pageContentId) {
          this.myForm = this.form;
          this.initFormWithSelectOptions();
        } else {
          this.updateForm(this.pageHelpContent);
        }
        this.showLoading = false;
        this.initCKEditor();
      },
      error => this.handleError('System error retrieving page with id: ' + pageId, error)
    ));
    
  }

  private initCKEditor() {
    this.cdr.detectChanges();
    if(this.ckEditor) {
      this.ckEditor.instance.on('mode', () => {
        let editor = this.ckEditor.instance;
        if (editor.mode === 'source') {
          let editable = editor.editable();
          editable.attachListener(editable, 'input', () => {
            this.myForm.get('content').setValue(editor.getData());
            this.myForm.get('content').markAsDirty();
            this.cdr.detectChanges();
          });
        }
      });
    }
  }

  private updateForm(pageHelpContent: PageHelpContent) {
    this.pageHelpContent = pageHelpContent;
    this.myForm = this.form;
    if (this.pageHelpContent) {
      this.myForm.patchValue((pageHelpContent));
    } else {
      this.initFormWithSelectOptions();
    }
    if (this.orderOptions.length == 1) {
      this.myForm.get('order').disable()
    }
    if (this.placementsOptions.length == 1) {
      this.myForm.get('placement').disable()
    }
    this.myForm.markAsPristine();
    
  }
  
  initFormWithSelectOptions() {
    if (this.placementsOptions.length == 1) {
      this.myForm.get("placement").setValue(this.placementsOptions[0].value);
    }
    this.myForm.get("order").setValue(this.orderOptions[this.orderOptions.length - 1].value);
    if (this.orderOptions.length == 1) {
      this.myForm.get('order').disable()
    }
    if (this.placementsOptions.length == 1) {
      this.myForm.get('placement').disable()
    }
  }
  
  public setOptions(page: Page, countContents: number) {
    this.placementsOptions = [];
    if (page.top) {
      this.placementsOptions.push({label: "top", value: "top"});
    }
    if (page.bottom) {
      this.placementsOptions.push({label: "bottom", value: "bottom"});
    }
    if (page.left) {
      this.placementsOptions.push({label: "left", value: "left"});
    }
    this.orderOptions = [];
    for (let i = 1; i < countContents + 1; i++) {
      this.orderOptions.push({label: "" + i, value: i});
    }
  }
  
  public get form() {
    return this._fb.group({
      page: [this.pageId, Validators.required],
      portal: this.portal,
      placement: ['', Validators.required],
      content: ['', Validators.required],
      order: [1, Validators.required],
      isActive: true,
      //isPriorTo : false,
      _id: '',
    });
  }
  
  public reset() {
    this.myForm.patchValue({
      page: '',
      portal: this.portal,
      placement: '',
      content: [''],
      order: 1,
      isActive: true,
      //isPriorTo : false,
      _id: ''
    });
    this.myForm.markAsPristine();
  }
  
  handleError(message: string, error = null) {
    if(error) {
      console.error('Server responded: ' + error);
    }
    NotificationHandler.rise(message, 'danger');
    this.showLoading = false;
  }
  
  public saveCustom() {
    if (this.myForm.valid) {
      this.showLoading = true;
      let pageHelpContent: PageHelpContent = this.myForm.getRawValue();
      this.subs.push(this._helpContentService.savePageHelpContent(pageHelpContent, this.properties.adminToolsAPIURL, this.portal).subscribe(
        _ => {
          NotificationHandler.rise('Page content has been <b>successfully ' + (this.pageContentId ? 'updated' : 'created') + '</b>');
          this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route});
          this.showLoading = false;
          this._clearCacheService.clearCacheInRoute("page help content saved",this.portal, this.page.route);
        },
        err => this.handleUpdateError('System error saving page content', err)
      ));
    } else {
      this.showLoading = false;
    }
  }
  
  public resetCustom() {
    this.showLoading = true;
    this.updateForm(this.pageHelpContent);
    this.showLoading = false;
  }
  
  handleUpdateError(message: string, error = null) {
    if(error) {
      console.error('Server responded: ' + error);
    }
    NotificationHandler.rise(message, 'danger');
    this.showLoading = false;
  }
  
  changeStatus() {
    this.myForm.get('isActive').setValue(!this.myForm.get('isActive').value);
    if (this.pageHelpContent && this.myForm.get('isActive').value != this.pageHelpContent.isActive || !this.pageHelpContent && !this.myForm.get('isActive').value) {
      this.myForm.get('isActive').markAsDirty();
    } else {
      this.myForm.get('isActive').markAsPristine()
    }
  }
  
  contentChanged() {
    if (this.pageHelpContent && this.myForm.get('content').value != this.pageHelpContent.content || !this.pageHelpContent && this.myForm.get('content').value != '') {
      this.myForm.get('content').markAsDirty();
    } else {
      this.myForm.get('content').markAsPristine()
    }
  }
}
