import {ChangeDetectorRef, Component, ElementRef, ViewChild} from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';

import {EnvProperties} from './openaireLibrary/utils/properties/env-properties';
import {MenuItem} from './openaireLibrary/sharedComponents/menu';
import {EnvironmentSpecificService} from './openaireLibrary/utils/properties/environment-specific.service';
import {Session, User} from './openaireLibrary/login/utils/helper.class';
import {UserManagementService} from "./openaireLibrary/services/user-management.service";
import {properties} from "../environments/environment";
import {Subscriber} from "rxjs";
import {StakeholderService} from "./openaireLibrary/monitor/services/stakeholder.service";
import {Header} from "./openaireLibrary/sharedComponents/navigationBar.component";
import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll";
import {QuickContactService} from './openaireLibrary/sharedComponents/quick-contact/quick-contact.service';
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
import {Composer} from "./openaireLibrary/utils/email/composer";
import {NotificationHandler} from "./openaireLibrary/utils/notification-handler";
import {EmailService} from "./openaireLibrary/utils/email/email.service";
import {StringUtils} from "./openaireLibrary/utils/string-utils.class";
import {QuickContactComponent} from "./openaireLibrary/sharedComponents/quick-contact/quick-contact.component";
import {AlertModal} from "./openaireLibrary/utils/modal/alert";
import {StakeholderEntities} from './openaireLibrary/monitor/entities/stakeholder';
import {ResourcesService} from "./openaireLibrary/monitor/services/resources.service";
import {LayoutService} from "./openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";

@Component({
  selector: 'app-root',
  template: `
    <div>
      <div id="modal-container"></div>
      <navbar *ngIf="properties && showMenu && header" portal="monitor" [header]="header" [onlyTop]="false"
              [userMenuItems]=userMenuItems [menuItems]=menuItems [user]="user"
              [showMenu]=showMenu [properties]="properties">
        <div *ngIf="showGetStarted" extra-s class="uk-margin-large-top uk-margin-left">
          <a class="uk-button uk-button-primary uk-text-uppercase" routerLink="/get-started">Get Started</a>
        </div>
        <a *ngIf="showGetStarted" extra-m class="uk-button uk-button-small uk-button-primary uk-text-uppercase uk-margin-left" routerLink="/get-started">Get Started</a>
      </navbar>
      <schema2jsonld *ngIf="properties " [URL]="properties.domain + properties.baseLink"
                     [logoURL]="properties.domain + properties.baseLink + logoPath + 'main.svg'"
                     type="home"
                     description="OpenAIRE - Monitor, A new era of monitoring research. Open data. Open methodologies. Work together with us to view, understand and visualize research statistics and indicators. "
                     name="OpenAIRE Monitor" [searchAction]="true"
                     [searchActionRoute]="properties.domain + properties.baseLink + '/browse'">
      </schema2jsonld>
      <div class="uk-background-default">
        <main>
          <router-outlet></router-outlet>
        </main>
      </div>
      <cookie-law position="bottom">
        OpenAIRE uses cookies in order to function properly.<br>
        Cookies are small pieces of data that websites store in your browser to allow us to give you the best browsing
        experience possible.
        By using the OpenAIRE portal you accept our use of cookies. <a
          href="https://www.openaire.eu/privacy-policy#cookies" target="_blank"> Read more <span class="uk-icon">
            <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="chevron-right"
                 ratio="1"><polyline fill="none" stroke="#000" stroke-width="1.03"
                                     points="7 4 13 10 7 16"></polyline></svg>
            </span></a>
      </cookie-law>
      <bottom #bottom *ngIf="properties && showMenu" id="bottom" [grantAdvance]="false"
			[properties]="properties"></bottom>
      <quick-contact #quickContact *ngIf="bottomNotIntersecting && displayQuickContact && showQuickContact && contactForm"
                     (sendEmitter)="send($event)"
                     [contactForm]="contactForm" [sending]="sending" [images]="images" [contact]="'Help'"
                     [organizationTypes]="organizationTypes"
										 class="uk-visible@m"></quick-contact>
      <modal-alert #modal [overflowBody]="false"></modal-alert>
    </div>
  `
  
})
export class AppComponent {
  userMenuItems: MenuItem[] = [];
  menuItems: MenuItem [] = [];
  bottomMenuItems: MenuItem[] = [];
  properties: EnvProperties = properties;
  showMenu: boolean = false;
  user: User;
  header: Header;
  logoPath: string = 'assets/common-assets/logo-services/monitor/';
  /* Contact */
  public showQuickContact: boolean;
  public bottomNotIntersecting: boolean;
  public displayQuickContact: boolean;  // intersecting with specific section in home page
  public showGetStarted: boolean = true;
  public contactForm: UntypedFormGroup;
  public organizationTypes: string[] = [
    'Funding agency', 'University / Research Center',
    'Research Infrastructure', 'Government',
    'Non-profit', 'Industry', 'Other'
  ];
  public images: string[] = ['assets/monitor-assets/curators/1.jpg', 'assets/monitor-assets/curators/2.jpg',
    'assets/monitor-assets/curators/3.jpg', 'assets/monitor-assets/curators/4.jpg']
  public sending = false;
  @ViewChild('modal') modal: AlertModal;
  @ViewChild('quickContact') quickContact: QuickContactComponent;
	@ViewChild('bottom', {read: ElementRef}) bottom: ElementRef;
  private subscriptions: any[] = [];
	public stakeholderEntities = StakeholderEntities;
  
  constructor(private route: ActivatedRoute, private propertiesService: EnvironmentSpecificService,
              private configurationService: ConfigurationService,
              private router: Router, private stakeholderService: StakeholderService, private smoothScroll: SmoothScroll,
              private userManagementService: UserManagementService,
              private quickContactService: QuickContactService,
              private layoutService: LayoutService,
              private fb: UntypedFormBuilder,
              private emailService: EmailService,
              private resourcesService: ResourcesService,
              private cdr: ChangeDetectorRef) {
    this.subscriptions.push(router.events.forEach((event) => {
      if (event instanceof NavigationEnd) {
        this.showGetStarted = event.url !== '/get-started';
      }
      
    }));
  }
  
  ngOnInit() {
    this.configurationService.initPortal(this.properties, "monitor");
    this.userManagementService.fixRedirectURL = properties.afterLoginRedirectLink;
    this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
      this.user = user;
      this.setUserMenu();
      this.header = {
        route: "/",
        url: null,
        title: 'monitor',
        logoUrl: this.logoPath + 'main.svg',
        logoSmallUrl: this.logoPath + 'small.svg',
        position: 'left',
        badge: true,
        menuPosition: 'center'
      };
      this.buildMenu();
      this.reset();
    }));
    this.subscriptions.push(this.layoutService.hasQuickContact.subscribe(hasQuickContact => {
      if(this.showQuickContact !== hasQuickContact) {
        this.showQuickContact = hasQuickContact;
        this.cdr.detectChanges();
      }
    }));
    this.subscriptions.push(this.quickContactService.isDisplayed.subscribe(display => {
      if(this.displayQuickContact !== display) {
        this.displayQuickContact = display;
        this.cdr.detectChanges();
      }
    }));
  }

	createObservers() {
		let options = {
			root: null,
			rootMargin: '0px',
			threshold: 0.1
		};

    let intersectionObserver = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        // if (entry.isIntersecting && this.showQuickContact) {
        if(this.bottomNotIntersecting !== (!entry.isIntersecting)) {
          this.bottomNotIntersecting = !entry.isIntersecting;
          this.cdr.detectChanges();
        }
      });
    }, options);
    intersectionObserver.observe(this.bottom.nativeElement);
    this.subscriptions.push(intersectionObserver);
	}
  
  public ngOnDestroy() {
    this.subscriptions.forEach(value => {
      if (value instanceof Subscriber) {
        value.unsubscribe();
      } else if (typeof IntersectionObserver !== "undefined" && value instanceof IntersectionObserver) {
        value.disconnect();
      }
    });
    this.userManagementService.clearSubscriptions();
    this.stakeholderService.clearSubscriptions();
    this.smoothScroll.clearSubscriptions();
  }

  public buildMenu() {
    this.menuItems = [];
    this.menuItems.push(
      new MenuItem("home", "Home", "", "/", false, [], null, {}, null, null, "uk-hidden@m")
    );
    this.menuItems.push(
      new MenuItem("stakeholders", "Browse " + this.stakeholderEntities.STAKEHOLDERS, "", "/browse", false, [], null, {})
    );
    this.resourcesService.setResources(this.menuItems);
    this.menuItems.push(new MenuItem("support", "Support", "", "/support", false, [], null, {}));
    this.menuItems.push(new MenuItem("about", "About", "", "/about", false, [], null, {}));
    this.bottomMenuItems = [
      new MenuItem("", "About", "https://beta.openaire.eu/project-factsheets", "", false, [], [], {}),
      new MenuItem("", "News - Events", "https://beta.openaire.eu/news-events", "", false, [], [], {}),
      new MenuItem("", "Blog", "https://blogs.openaire.eu/", "", false, [], [], {}),
      new MenuItem("", "Contact us", "https://beta.openaire.eu/contact-us", "", false, [], [], {})
    ];
    this.menuItems.push(
      new MenuItem("contact-us", "Contact us", "", "/contact-us", false, [], null, {}, null, null, "uk-hidden@m")
    );
    this.showMenu = true;
    if(typeof document !== 'undefined') {
      setTimeout(() => {
        this.createObservers();
      })
    }
  }
  
  public setUserMenu() {
    this.userMenuItems = [];
    if (this.user) {
      if (Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user) || Session.isKindOfMonitorManager(this.user)) {
        this.userMenuItems.push(new MenuItem("", "Manage profiles",
          this.properties.domain + properties.baseLink + "/dashboard/admin", "", false, [], [], {}, null, null, null, null, "_self"));
      }
      this.userMenuItems.push(new MenuItem("", "My " + this.stakeholderEntities.STAKEHOLDERS, "", "/my-dashboards", false, [], [], {}));
      this.userMenuItems.push(new MenuItem("", "User information", "", "/user-info", false, [], [], {}));
    }
  }
  
  public send(event) {
    if (event.valid === true) {
      this.sendMail(this.properties.admins);
    }
  }
  
  public reset() {
    if (this.quickContact) {
      this.quickContact.close();
    }
    this.contactForm = this.fb.group({
      name: this.fb.control('', Validators.required),
      surname: this.fb.control('', Validators.required),
      email: this.fb.control('', [Validators.required, Validators.email]),
      job: this.fb.control('', Validators.required),
      organization: this.fb.control('', Validators.required),
      organizationType: this.fb.control('', [Validators.required, StringUtils.validatorType(this.organizationTypes)]),
      message: this.fb.control('', Validators.required),
      recaptcha: this.fb.control('', Validators.required),
    });
  }
  
  private sendMail(admins: string[]) {
    this.sending = true;
    this.subscriptions.push(this.emailService.contact(this.properties,
      Composer.composeEmailForMonitor(this.contactForm.value, admins),
      this.contactForm.value.recaptcha).subscribe(
      res => {
        if (res) {
          this.sending = false;
          this.reset();
          this.modalOpen();
        } else {
          this.handleError('Email <b>sent failed!</b> Please try again.');
        }
      },
      error => {
        this.handleError('Email <b>sent failed!</b> Please try again.', error);
      }
    ));
  }
  
  public modalOpen() {
    this.modal.okButton = true;
    this.modal.alertTitle = 'Your request has been successfully submitted';
    this.modal.message = 'Our team will respond to your submission soon.';
    this.modal.cancelButton = false;
    this.modal.okButtonLeft = false;
    this.modal.okButtonText = 'OK';
    this.modal.open();
  }
  
  handleError(message: string, error = null) {
    if (error) {
      console.error(error);
    }
    this.sending = false;
    this.quickContact.close();
    NotificationHandler.rise(message, 'danger');
    this.contactForm.get('recaptcha').setValue('');
  }
}
