import { AfterViewInit, Component, OnDestroy, OnInit, Optional, ViewChild } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IClientModel } from '@fleio-api/client-user/model/client.model';
import { ConfigService } from '@shared/config/config.service';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { UploadInterfaceComponent } from '@shared/ui/upload-interface/upload-interface.component';
import { IClientCreateOptions } from '@fleio-api/client-user/model/client-create-options';
import { ActivatedRoute, Router } from '@angular/router';
import { NotificationService } from '@shared/ui-api/notification.service';
import { ClientsApiService } from '@fleio-api/client-user/client/clients-api.service';
import { EMPTY, Observable, of } from 'rxjs';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import { IImageModel } from '@fleio-api/openstack/model/image.model';
import { ThemingService } from '@shared/ui/theming/theming.service';
import { EditorComponent } from '@tinymce/tinymce-angular';
import { TinymceHelper } from '@shared/ui-api/helpers/tinymce-helper';
import * as _moment from 'moment';
import { PanelLayoutComponent } from '@shared/layout/panel-layout/panel-layout.component';
import { MatDialog } from '@angular/material/dialog';
import { TimeHelper } from '@shared/ui-api/helpers/time-helper';
import { ValidatorsHelper } from '@shared/ui-api/helpers/validators-helper';
import { IIcon } from '@shared/ui/common/interfaces/icon';
import {
  InsertMassMessageTemplateDialogComponent
} from '../../dialogs/insert-mass-message-template-dialog/insert-mass-message-template-dialog.component';

const TOP_LINE_DEFAULT_BG = '#fff59d';
const TOP_LINE_DEFAULT_TXT_COLOR = '#000';

@Component({
  selector: 'app-client-send-mass-message-form',
  templateUrl: './client-send-mass-message-form.component.html',
  styleUrls: ['./client-send-mass-message-form.component.scss'],
})
export class ClientSendMassMessageFormComponent extends DetailsFormBase<IClientModel>
  implements OnInit, OnDestroy, AfterViewInit {

  @ViewChild('uploadInterface') uploadInterface: UploadInterfaceComponent;
  @ViewChild('tinyMceArea') tinyMceArea: EditorComponent;
  tinyMceHelper = new TinymceHelper();
  massEmailForm = this.formBuilder.group({
    message_type: ['email_and_message', Validators.required],
    targeted_notifications: [''],
    top_line_notification: [false],
    show_top_line_until: [null],
    show_top_line_until_time: [null],
    top_line_background_color: [
      TOP_LINE_DEFAULT_BG, [Validators.minLength(4), Validators.maxLength(7)]
    ],
    top_line_text_color: [
      TOP_LINE_DEFAULT_TXT_COLOR, [Validators.minLength(4), Validators.maxLength(7)]
    ],
    from_name: [''],
    from_email: ['', Validators.required],
    subject: ['', Validators.required],
    body: ['', Validators.required],
    send_batch_size: [16, [ValidatorsHelper.requiredIntegerValidator, Validators.min(1)]],
    send_interval: [30, [ValidatorsHelper.requiredIntegerValidator, Validators.min(1)]],
    filter: [''],
    search: [''],
  });
  filteringString = '';
  searchingString = '';
  tinyMCEOptions: any;
  maxAttachmentSize = 10 * 1024 * 1024;
  createOptions: IClientCreateOptions;
  uploading = false;
  uploadProgress: number;
  clientsCount = 0;
  topPanelNotificationPreview = false;
  messageType = this.massEmailForm.controls.message_type;
  insertTemplateIcon: IIcon = {
    name: 'info',
    tooltip: $localize`(subject, body, destination & message type taken from template)`,
    verticalAlign: 'middle',
  };
  timeHelper: TimeHelper;

  constructor(
    private config: ConfigService,
    private formBuilder: UntypedFormBuilder,
    private matDialog: MatDialog,
    private activatedRoute: ActivatedRoute,
    private notificationService: NotificationService,
    private clientsApiService: ClientsApiService,
    private router: Router,
    private themingService: ThemingService,
    @Optional() public panelLayout?: PanelLayoutComponent,
  ) {
    super();
    this.timeHelper = new TimeHelper(config);
    this.massEmailForm.controls.show_top_line_until_time.setValidators(
      [ValidatorsHelper.timeValidator(this.timeHelper.timeFormat, this.timeHelper.timeExample)]
    );
  }

  changedPreviewOpt(value) {
    if (value && value.checked) {
      const topLineData = {
        title: 'This is a preview of a possible top panel notification (read more disabled).',
        top_line_preview: true,
      } as any;
      this.panelLayout.panelNotifications = [topLineData];
      this.panelLayout.shownPanelNotifications = [topLineData];
      const bgColorCtrl = this.massEmailForm.controls.top_line_background_color;
      if (bgColorCtrl.valid) {
        this.panelLayout.shownPanelNotifications[0].top_line_background_color = bgColorCtrl.value;
      }
      const txtColorCtrl = this.massEmailForm.controls.top_line_text_color;
      if (txtColorCtrl.valid) {
        this.panelLayout.shownPanelNotifications[0].top_line_text_color = txtColorCtrl.value;
      }
      this.panelLayout.calculateAppOffset();
    } else {
      this.removeTopLinePreview();
    }
  }

  removeTopLinePreview() {
    this.panelLayout.panelNotifications = [];
    this.panelLayout.shownPanelNotifications = [];
    this.panelLayout.calculateAppOffset();
  }

  ngOnInit(): void {
    super.ngOnInit();
    if (this.objectController) {
      this.objectController.actionCallback = () => this.sendMassEmail();
    }
    this.createOptions = this.activatedRoute.snapshot.data.createOptions;
    if (this.createOptions && this.createOptions.default_from_email) {
      let email;
      let name;
      if (this.createOptions.default_from_email) {
        if (this.createOptions.default_from_email.includes('<') && this.createOptions.default_from_email.includes('>')) {
          email = this.createOptions.default_from_email.substring(
            this.createOptions.default_from_email.indexOf('<') + 1, this.createOptions.default_from_email.indexOf('>')
          );
          name = this.createOptions.default_from_email.substring(
            0, this.createOptions.default_from_email.indexOf('<')
          ).trim();
        } else {
          email = this.createOptions.default_from_email;
        }
        this.massEmailForm.controls.from_email.setValue(email);
      }
      if (name) {
        this.massEmailForm.controls.from_name.setValue(name);
      }
    }
    if (this.config && this.config.current) {
      this.tinyMCEOptions = this.themingService.getTinyMceOptions();
    }
    this.initClientFilteringData();
    this.clientsApiService.list({
      filtering: this.filteringString,
      search: this.searchingString,
    }).subscribe(response => {
      this.clientsCount = response.totalCount;
      if (!this.clientsCount) {
        this.router.navigateByUrl(this.config.getPanelUrl('clients-users/mass-mail'));
        this.notificationService.showMessage($localize`No clients selected!`);
      }
    });
    this.messageType.valueChanges.subscribe(value => {
      if (['email_and_message', 'message'].indexOf(value) < 0) {
        this.massEmailForm.controls.top_line_notification.setValue(false);
      }
    });
    this.massEmailForm.controls.top_line_background_color.valueChanges.subscribe(value => {
      if (this.panelLayout.shownPanelNotifications && this.panelLayout.shownPanelNotifications.length &&
        value && value[0] === '#' && value.length > 3) {
        this.panelLayout.shownPanelNotifications[0].top_line_background_color = value;
      }
    });
    this.massEmailForm.controls.top_line_text_color.valueChanges.subscribe(value => {
      if (this.panelLayout.shownPanelNotifications && this.panelLayout.shownPanelNotifications.length &&
        value && value[0] === '#' && value.length > 3) {
        this.panelLayout.shownPanelNotifications[0].top_line_text_color = value;
      }
    });
    this.massEmailForm.controls.top_line_notification.valueChanges.subscribe(value => {
      if (value === false) {
        // reset top line settings
        this.massEmailForm.controls.top_line_background_color.setValue(TOP_LINE_DEFAULT_BG);
        this.massEmailForm.controls.top_line_text_color.setValue(TOP_LINE_DEFAULT_TXT_COLOR);
        this.massEmailForm.controls.show_top_line_until.setValue(null);
        this.topPanelNotificationPreview = false;
        this.removeTopLinePreview();
      }
    });
  }

  clickVariable(item: string) {
    const textArea = document.createElement('textarea');
    textArea.value = item;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand('Copy');
    textArea.remove();
    this.notificationService.showMessage($localize`Successfully copied`);
  }

  sendMassEmail(): Observable<IActionResult> {
    const value = this.massEmailForm.value;
    const formData = new FormData();
    for (const key in value) {
      if (value.hasOwnProperty(key)) {
        if (key === 'show_top_line_until') {
          if (value[key]) {
            if (this.timeHelper.processDateFieldTime(value[key], this.massEmailForm.controls.show_top_line_until_time).error) {
              return of(null);
            }
            // noinspection SpellCheckingInspection
            formData.append(key, _moment(value[key]).format('YYYY-MM-DDTHH:mm:ssZ'));
          }
        } else {
          formData.append(key, value[key]);
        }
      }
    }

    if (this.uploadInterface) {
      const fileInputs = this.uploadInterface.getFileInputs();
      const allFiles = [];
      for (const fileInput of fileInputs) {
        if (fileInput && fileInput.nativeElement.files.length) {
          // on send mass email, for one input there is at most one file
          allFiles.push(fileInput.nativeElement.files[0]);
        }
      }
      let i = 0;
      for (const file of allFiles) {
        formData.append('file_data_' + i, file);
        formData.append('file_name_' + i, file.name);
        i++;
      }
    }

    const response = this.createOrUpdate(
      this.clientsApiService,
      formData,
      false,
      'send_mass_message'
    );

    if (response !== EMPTY) {
      this.primaryAction.disabled = true;
      this.uploading = !!formData;
      response.subscribe((data) => {
        let requestCompleted = false;
        if (formData) {
          const event = data as HttpEvent<IImageModel>;
          if (event.type === HttpEventType.UploadProgress) {
            this.uploadProgress = event.loaded / event.total * 100;
          }

          if (event.type === HttpEventType.Response) {
            requestCompleted = true;
          }
        } else {
          requestCompleted = true;
        }

        if (requestCompleted) {
          this.uploading = false;
          this.notificationService.showMessage($localize`Send mass mail task queued`);
          this.router.navigateByUrl(
            this.config.getPrevUrl('clients-users/mass-message')
          ).catch(() => {
          });
        }
      }).add(() => {
        this.primaryAction.disabled = false;
      });
    }
    return of(null);
  }

  initClientFilteringData() {
    const url = this.config.getCurrentUrl();
    if (url.includes('clients')) {
      const filteringSearchNeedle = 'filtering=';
      const filteringIndex = url.indexOf(filteringSearchNeedle);
      if (filteringIndex > -1) {
        let i = filteringIndex + filteringSearchNeedle.length;
        while (url[i] !== '&' && url[i]) {
          this.filteringString += url[i];
          i++;
        }
      }
      if (this.filteringString) {
        this.filteringString = decodeURIComponent(this.filteringString);
      }
      const searchingSearchNeedle = 'search=';
      const searchingIndex = url.indexOf(searchingSearchNeedle);
      if (searchingIndex > -1) {
        let j = searchingIndex + searchingSearchNeedle.length;
        while (url[j] !== '&' && url[j]) {
          this.searchingString += url[j];
          j++;
        }
      }
      if (this.searchingString) {
        this.searchingString = decodeURIComponent(this.searchingString);
      }
      this.massEmailForm.controls.filter.setValue(this.filteringString);
      this.massEmailForm.controls.search.setValue(this.searchingString);
    }
  }

  openInsertMassMessageTemplateDialog() {
    return this.matDialog.open(
      InsertMassMessageTemplateDialogComponent, {
        autoFocus: false,
      }
    ).afterClosed().subscribe(result => {
        if (!result) {
          return;
        }
        let messageType;
        if (result.target === 'email_and_ui') {
          messageType = 'email_and_message';
        } else if (result.target === 'email') {
          messageType = 'email';
        } else if (result.target === 'ui') {
          messageType = 'message';
        }
        this.massEmailForm.controls.message_type.setValue(messageType);
        this.massEmailForm.controls.targeted_notifications.setValue(result.target_category);
        this.massEmailForm.controls.subject.setValue(result.title);
        this.massEmailForm.controls.body.setValue(result.content);
        return {message: result} as IActionResult;
    });
  }

  ngAfterViewInit() {
    super.ngAfterViewInit();
    this.tinyMceHelper.manageUndo(this.massEmailForm.controls.body, this.tinyMceArea);
  }

  handleTinyKeyDown(event) {
    if (event && event.event && event.event.ctrlKey && event.event.keyCode === 13) {
      event.event.preventDefault();
      this.sendMassEmail();
    }
  }

  ngOnDestroy() {
    super.ngOnDestroy();
    this.tinyMceHelper.removeSubscriptionForUndo();
  }
}
