import { Component, OnInit } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { IMessageTemplateCreateOptionsModel } from '@fleio-api/message-templates/model/message-template-create-options';
import { ActivatedRoute } from '@angular/router';
import { NotificationService } from '@shared/ui-api/notification.service';
import { IMessageTemplateModel } from '@fleio-api/message-templates/model/message-template.model';
import { ConfigService } from '@shared/config/config.service';
import { MatDialog } from '@angular/material/dialog';
import { AddNewTemplateDialogComponent } from '../../dialogs/add-new-template-dialog/add-new-template-dialog.component';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { Observable, of } from 'rxjs';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { ITemplateLanguageModel } from '@fleio-api/message-templates/model/template-language.model';
import { MessageTemplatesApiService } from '@fleio-api/message-templates/message-templates-api.service';
import { RefreshService } from '@shared/ui-api/refresh.service';
import { ThemingService } from '@shared/ui/theming/theming.service';

const EMAIL_ONLY_TEMPLATES = [
  'account.user.invitation', 'account.reset.password', 'staff.account.reset.password', 'account.signup.confirm',
  'staff.openstack.error',
]; // these templates cannot be sent as UI notification because are not attached to a Client instance

@Component({
  selector: 'app-message-template-edit-form',
  templateUrl: './message-template-edit-form.component.html',
  styleUrls: ['./message-template-edit-form.component.scss']
})
export class MessageTemplateEditFormComponent
  extends DetailsFormBase<IMessageTemplateModel> implements OnInit {
  createOptions: IMessageTemplateCreateOptionsModel;
  templateName: string;
  messageTemplatesForm = this.formBuilder.group({
    disable_notification: [false],
    target: [null, Validators.required],
    target_category: [''],
  });
  templateGroups:{[key:string]: UntypedFormGroup} = {}

  tinyMCEOptions = null;
  availableLanguages: ITemplateLanguageModel[] = [];
  clickToCopyTooltip = $localize`Click to copy`;
  fieldRequiredTxt = $localize`This field is required!`;
  isEmailOnly = false;

  constructor(
    private formBuilder: UntypedFormBuilder, private activatedRoute: ActivatedRoute, private matDialog: MatDialog,
    private notificationService: NotificationService, private config: ConfigService,
    private messageTemplatesApiService: MessageTemplatesApiService, private refreshService: RefreshService,
    private themingService: ThemingService,
  ) {
    super();
    this.focusFirstInput = false;
  }

  public messageTemplates: IMessageTemplateModel[] = [];

  ngOnInit(): void {
    super.ngOnInit();
    if (this.config.current) {
      this.tinyMCEOptions = this.themingService.getTinyMceOptions();
    }
    this.init();
  }

  private init() {
    if (this.object) {
      this.messageTemplates = JSON.parse(JSON.stringify(this.object)) as IMessageTemplateModel[];
      this.createOptions = this.activatedRoute.snapshot.data.createOptions;
      if (this.messageTemplates[0].type === 'system') {
        this.messageTemplatesForm.controls.target_category.disable();
      }
      this.messageTemplatesForm.controls.disable_notification.setValue(
        this.messageTemplates[0].disable_notification
      );
      this.messageTemplatesForm.controls.target.setValue(
        this.messageTemplates[0].target
      );
      this.messageTemplatesForm.controls.target_category.setValue(
        this.messageTemplates[0].target_category || ''
      );
      this.templateName = this.messageTemplates[0].name;
      this.isEmailOnly = EMAIL_ONLY_TEMPLATES.includes(this.templateName);
      if (this.isEmailOnly) {
        this.messageTemplatesForm.controls.target.disable();
      }
      this.availableLanguages = this.createOptions.languages.filter(
        lang => !this.messageTemplates[0].template_languages.includes(lang.language_code)
      );
      if (this.objectController) {
        this.objectController.actionCallback = (action) => this.tabAction(action);
      }

      for (const template of this.messageTemplates) {
        const groupControls: any = {};
        const groupName = `template${template.id}`;
        groupControls.title = [template.title, Validators.required];
        groupControls.content = [template.content, Validators.required];
        const group = this.formBuilder.group(groupControls);
        this.messageTemplatesForm.addControl(groupName, group);
        this.templateGroups[groupName] = group;
      }

      if (!this.objectController.permissions['messagetemplates.update']) {
        this.messageTemplatesForm.disable();
      }
    }
  }

  tabAction(action: CallbackAction): Observable<IActionResult> {
    if (action.internalName.toLowerCase() === 'add') {
      this.addNewTemplate();
    }
    if (action.internalName.toLowerCase() === 'save') {
      this.saveTemplates();
    }

    return of({message: $localize`Action executed`});
  }

  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`);
  }

  deleteTemplate(template: IMessageTemplateModel) {
    this.notificationService.confirmDialog({
      title: $localize`Delete template ${this.templateName} - ${template.language_display}`,
      message: $localize`Are you sure you want to delete template ${this.templateName} - ${template.language_display}?`,
    }).subscribe(result => {
      if (result?.button === 'yes') {
        this.messageTemplatesApiService.delete(template.id).subscribe({
          next:
            () => {
              this.notificationService.showMessage($localize`Template deleted`);
              this.refreshService.refresh(() => {
                this.init();
              });
            },
          error: error => {
            if (error.error && error.error.detail) {
              this.notificationService.showMessage(error.error.detail);
            } else {
              this.notificationService.showMessage($localize`Failed to delete template`);
            }
          }
        });
      }
    });
  }

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

  saveTemplates() {
    this.validate();
    if (this.messageTemplatesForm.invalid) {
      this.displayControlErrors();
      this.setErrors({detail: $localize`Your form contains errors.`});
      return;
    }

    for (const template of this.messageTemplates) {
      const formValue = this.messageTemplatesForm.controls[`template${template.id}`].value;
      template.title = formValue.title;
      template.content = formValue.content;
      template.disable_notification = this.messageTemplatesForm.controls.disable_notification.value;
      template.target = this.messageTemplatesForm.controls.target.value;
      template.target_category = this.messageTemplatesForm.controls.target_category.value;
    }

    this.objectController.loading = true;
    this.messageTemplatesApiService.updateTemplatesSet(this.messageTemplates).subscribe(
      () => {
        this.notificationService.showMessage($localize`Templates saved successfully`);
        this.refreshService.refresh();
      },
      error => {
        if (error?.error) {
          this.setErrors(error.error);
        } else {
          this.setErrors({detail: $localize`Failed to save templates, check logs for details.`});
        }
      }
    ).add(() => {
      this.objectController.loading = false;
    });
  }

  addNewTemplate() {
    return this.matDialog.open(
      AddNewTemplateDialogComponent, {
        data: {
          availableLanguages: this.availableLanguages,
          templateName: this.templateName,
        },
        autoFocus: false,
      }).afterClosed().subscribe(result => {
      if (result && result !== 'close') {
        this.messageTemplatesApiService.createTemplate(
          this.templateName, result,
        ).subscribe(
          () => {
            this.notificationService.showMessage($localize`New template added`);
            this.refreshService.refresh(() => {
              this.init();
            });
          },
          error => {
            if (error.error && error.error.detail) {
              this.notificationService.showMessage(error.error.detail);
            } else {
              this.notificationService.showMessage($localize`Failed to add new template`);
            }
          }
        );
      }
    });
  }

  isDefault(template: IMessageTemplateModel): boolean {
    const templateGroup = this.messageTemplatesForm.controls['template' + template.id] as UntypedFormGroup;
    const isDefault = templateGroup.controls['content'].getRawValue()
      .replace(/(\r\n|\r|\n)/g, '') === template.default_content.replace(/(\r\n|\r|\n)/g, '');

    return isDefault;
  }

  loadDefault(template: IMessageTemplateModel) {
    if (template.default_content) {
      const templateGroup = this.messageTemplatesForm.controls['template' + template.id] as UntypedFormGroup;
      templateGroup.controls['content'].setValue(template.default_content);
    }
  }
}
