import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, Router, UrlSegment } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { MenuItem, MessageService } from 'primeng/api';
import { OverlayPanel } from 'primeng/overlaypanel';
import { Subscription } from 'rxjs';
import { Layout } from "src/app/widgets/Layout";
import { Configuration, Page } from "src/app/models/Page";
import { PageService } from 'src/app/services/page.service';
import { UtilsService } from 'src/app/services/utils.service';

@Component({
  selector: 'app-pages',
  templateUrl: './pages.component.html',
  styleUrls: ['./pages.component.css']
})
export class PagesComponent implements OnInit, OnDestroy {

  disposeOnDestroySubscriptions: Subscription[] = [];

  slug?: string;
  pageId?: string;
  view: boolean = false;
  edit: boolean = false;
  pages: Page[] = [];
  page?: Page;
  configuration?: Configuration;

  languages: string[] = [];

  menuItemsViewButton: MenuItem[] = [];
  lastSavedPageHash: string = "";

  get list() {
    return !this.slug && !this.pageId;
  }

  constructor(
    private translate: TranslateService,
    private activatedRoute: ActivatedRoute, 
    private router: Router, 
    private pageService: PageService, 
    private messageService: MessageService,
    private utils: UtilsService) { }

  ngOnInit(): void {

    this.languages = this.translate.getLangs();

    this.initMenuItemsForViewSplitButton();

    this.disposeOnDestroySubscriptions.push(
      this.translate.onLangChange.subscribe( _ => this.initMenuItemsForViewSplitButton() )
    );

    this.activatedRoute.params.subscribe(params => {
      this.slug = params?.slug;
      this.pageId = params?.id;
      this.view = !!params?.id && this.urlContainsPath(this.activatedRoute.snapshot.pathFromRoot, "view");      
      this.edit = !!params?.id && this.urlContainsPath(this.activatedRoute.snapshot.pathFromRoot, "edit");      

      if (this.list)
        this.loadPagesList();

      if (this.slug)
        this.loadPageDetailsBySlug();
        
      if (this.pageId)
        this.loadPageDetailsById();
    });
  }

  ngOnDestroy() {
    for (const subscription of this.disposeOnDestroySubscriptions)
        subscription.unsubscribe();
  }
  private initMenuItemsForViewSplitButton() {
    this.menuItemsViewButton = [
      {
        label: this.translate.instant('PAGES.VIEW_PAGE_BUTTON_SLUG'), icon: 'pi pi-eye', command: () => {
          this.viewPageBySlug(undefined, false);
        }
      },
      { separator: true },
      {
        label: this.translate.instant('PAGES.VIEW_PAGE_BUTTON_SLUG_NEW_PAGE'), icon: 'pi pi-external-link', command: () => {
          this.viewPageBySlug();
        }
      },
    ];
  }

  loadPagesList() {
    this.pages = [];
    this.pageService.getAllPages().subscribe(
      pages => {
        this.pages = pages;
      },
      error => {
        this.messageService.add({severity:'error', summary: 'Page list', detail: error })
      });
    // throw new Error('Method not implemented.');
  }

  goToList() {
    this.router.navigateByUrl("/pages");
  }

  newPage(pageNameTextbox: any, overlayPanel: OverlayPanel, language: string) {    

    const pageName = pageNameTextbox.value;

    if (!pageName) {
      this.utils.showWarnMessageTrans("PAGES.NEW.PAGE_NAME_REQUIRED");
      return;
    }

    pageNameTextbox.value = "";
    overlayPanel.hide();

    this.pageService.save(new Page({ name: pageName, lang: language }))
      .subscribe(savedPage => {     
        this.utils.showInfoMessageTrans("PAGES.NEW.PAGE_SAVED_CAN_EDIT");
        this.editPage(savedPage);
      },
      error => {
        this.utils.showErrorMessage(error);
      });
  }

  editPage(page?: Page) {    
    const id = page?.id ?? this.pageId;
    this.router.navigateByUrl("/pages/edit/" + id);
  }

  viewPage(page?: Page) {
    const id = page?.id ?? this.pageId;

    if (this.isEditingAndPageHasChanged()) {
      this.utils.showWarnMessageTrans("PAGES.PAGE_CHANGED_PLEASE_SAVE");
      return;
    }

    this.router.navigateByUrl("/pages/view/" + id);
  }

  private isEditingAndPageHasChanged() {
    return this.edit && this.lastSavedPageHash !== this.page?.getHash();
  }

  viewPageBySlug(page?: Page, openInNewTab: boolean = true) {
    if (!page)
      page = this.page;
    const slug = page?.slug ?? this.slug ?? this.page?.slug;
    let link = "/pages/" + slug;
    if (!page?.dynamic)
      link = page?.path || '';
    if (openInNewTab) {
      const url = this.router.serializeUrl(
        this.router.createUrlTree([link])
      );
    
      window.open(url, '_blank');
    }
    else
      this.router.navigateByUrl(link);
  }

  savePage() {
    if (!this.page) {
      this.utils.showErrorMessage("No page found.");
      return;
    }
    this.pageService.save(this.page)
      .subscribe(_ => {     
        this.lastSavedPageHash = this.page!.getHash();
        this.utils.showInfoMessageTrans("PAGES.NEW.PAGE_SAVED");
      },
      error => {
        this.utils.showErrorMessage(error);
      });
  }

  deletePage(page?: Page) {    
    const id = page?.id ?? this.pageId;
    //this.messageService.add({severity:'info', summary: 'Delete', detail: "Deleted called for: " + page?.slug })
    this.pageService.deletePage({id: id}).subscribe({
      next: response => {
        this.messageService.add({severity:'info', summary: 'Delete', detail: "Pag: " + page?.slug + " deleted successfully"});
        this.loadPagesList();
      }
    });
  }

  public urlContainsPath(pathFromRoot: ActivatedRouteSnapshot[], path: string): boolean {
    const urlSegmentsContains = (urlSegments: UrlSegment[], _path: string) => {
      return urlSegments.filter(o => o.path === _path).length > 0;
    };

    return pathFromRoot.filter(o => urlSegmentsContains(o.url, path)).length > 0;
  }

  loadPageDetailsById() {
    this.configuration = undefined;

    this.pageService.getPage(this.pageId??"").subscribe(
      page => {
        this.page = page;
        this.lastSavedPageHash = this.page.getHash();
        this.configuration = page.configuration;
        //console.info(this.configuration);
      },
      error => this.messageService.add({severity:'error', summary: 'Page', detail: error })
    );
  }

  loadPageDetailsBySlug() {
    this.configuration = undefined;

    this.pageService.getPageConfiguration(this.slug??"").subscribe(
      configuration => {
        this.configuration = configuration;
      },
      error => this.messageService.add({severity:'error', summary: 'Page', detail: error })
    );
  }

}
