import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal, ViewChild} from '@angular/core';

import { StaffView ,StaffSearch, Person } from '../models';


import { take } from 'rxjs/operators';
import { Subscription } from 'rxjs';
import { Router } from '@angular/router';
import { PersonService } from './person.service';
import { AuthenticationService } from '../user-services';
import { Table, TableModule } from 'primeng/table';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';
import { DialogService } from 'primeng/dynamicdialog';
import { PersonEdit } from './person.edit';
import { ConfirmationService, MenuItem, MessageService } from 'primeng/api';
import { IconFieldModule } from 'primeng/iconfield';
import { InputIconModule } from 'primeng/inputicon';
import { Menu, MenuModule } from 'primeng/menu';
import { FamilyOrga } from './family.orga';

import { saveAs } from 'file-saver';
import * as XLSX from 'xlsx';

@Component({
  selector: 'family-list',
  templateUrl: './familylist.html',
  imports:[TableModule,FormsModule,CommonModule,ButtonModule,MenuModule,
            InputTextModule,IconFieldModule,InputIconModule],
  styleUrls: ['./familylist.css'],
  providers: [DialogService]
})
export class FamilyList implements OnInit, OnDestroy{

  private subscription:Subscription = new Subscription();
  //private cd = inject(ChangeDetectorRef);
    items: MenuItem[] | undefined;
    selectedPerson!: Person;
    firstname = '';
    email = '';
    lastname = '';
    _id = -10;
    selectId = -1;
    loading = false;
    familyList = signal<Person[]>([]);
    msg ="[Person component]";
    @ViewChild(Table) dt2!: Table;
    @ViewChild('rowmenu') popMenu?: Menu;
    private messageService = inject(MessageService);
    public dialogService= inject( DialogService);
    private personService= inject( PersonService);
    private confirmationService = inject(ConfirmationService);
    private cdr = inject(ChangeDetectorRef);
    private authenticationService= inject( AuthenticationService);
    private router= inject( Router);
  
    getSearchCiteria(): StaffSearch {
    let criteria:StaffSearch = {
      email: this.email,
      firstName: this.firstname,
      lastName: this.lastname,
    };
    console.log("get search citeria", criteria);
    return criteria;

  }
  initMenu(): void {
    this.items = [            
                    {
                        label: 'Edit',
                        icon: 'pi pi-pencil',
                        command: () => { 
                        this.edit(this.selectId);         
                      }  
                    },
                    {
                        label: 'Delete',
                        icon: 'pi pi-times',
                        command: () => { 
                        this.delete(this.selectId);         
                      }  
                    },
                    {
                        label: 'Show Family',
                        icon: 'pi pi-sitemap',
                        command: () => {
                          this.showChildren(this.selectId);
                        }
                    }
            
        ];
  }
  exportExport() : void {
    this.ExcelExport(this.familyList(), 'family_export');
  }

  ExcelExport(data: any, fileName:string) :void
   {
    const worksheet = XLSX.utils.json_to_sheet(data);
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
    saveAs(blob, `${fileName}.xlsx`);
  }

  actionClick(id: number, event:Event): void {
    // console.log("action edit "+ id);
    this.selectId = id;
    this.popMenu!.toggle(event);
  }
  showChildren(id: number): void {
    console.log("show children of id", id);
    this.showOrganise(id);

}
  handleInput(event: Event) {
    const value = (event.target as HTMLInputElement).value;
    this.dt2.filterGlobal(value, 'contains');
  }
  canSearch():boolean {
    let result = false;
    result = this.email !== "";
    result = result || this.lastname !== "";
    result = result || this.firstname !== "";
    return result;
  }
  onMenuShow(): void {
    console.log("this is show", this.selectedPerson);
  }

  ngOnInit(): void
  { 
    this.initMenu();
    this.authenticationService.isHome = false;
    this.authenticationService.isReport = false;
  const prev = this.personService.searchCriteria;
    let goload = true;
    if (prev.lastName !== '')
    { 
      this.lastname = prev.lastName;
      goload = true;
    }
    if (prev.firstName !== '')
    {
      this.firstname = prev.firstName;
      goload = true;
    }
    if (prev.email !== '')
    {
      this.email = prev.email;
      goload = true;
    }
    if (goload)
    {
      this.search();
    }
  }  
  getActive(active:boolean):string {
    let result = 'false-icon pi-times-circle';
    if (active)
      result = 'true-icon pi-check-circle';
    return result;
  }
  search():void {
    const canSearch = true; // this.canSearch();
    if (canSearch)
    {
      this.loading = true;
      const criteria = this.getSearchCiteria();
       this.personService.searchCriteria = criteria;
      this.subscription.add(
      this.personService.searchPersons(criteria).subscribe( {
        next: result => {
      //  console.log(this.msg + "search load Data", result);      
        const familyList = result.data;
        this.familyList.set(familyList);
        this.updateParent( this.familyList());
         //this.familyList.set(familyList);
        
         console.log("the person from load", this.familyList());
        this.loading = false;
        this.cdr.detectChanges();
      }, 
      error: e => {      
      const message = e || e.message;
     // this.toastr.error(message);
     this.loading = false;
      console.log("error ", e);
      }
      }) 
    );
   }
  }
  getName(id:number): string
  {
    let result ="";
    const item = this.familyList().find(x => x.id == id);
    if (item)
      result = item.lastName + " " + item.firstName;
    return result;
  }
  updateParent(list:Person[]):void {
    let i = 0;
    let item:Person;
    for (i = 0; i< list.length; i++)
    {
      item = list[i];
      if (item.fatherId && item.fatherId > 0)
      {
        item.fatherName = this.getName(item.fatherId);
      }
      if (item.motherId && item.motherId > 0)
      {
        item.motherName = this.getName(item.motherId);
      }
    }
  }

  delete(id: number): void {
    this.confirmationService.confirm({
            
            message: 'Do you want to delete this record?',
            header: 'Confirmation Delete',
            icon: 'pi pi-info-circle',
            rejectLabel: 'Cancel',
            rejectButtonProps: {
                label: 'Cancel',
                severity: 'secondary',
                outlined: true,
            },
            acceptButtonProps: {
                label: 'Delete',
                severity: 'danger',
            },

            accept: () => {
                this.deleteItem(id);
            }
          });
  }

 deleteItem(id: number): void {
    this.personService.deletePerson(id)
      .pipe(take(1))
      .subscribe({ next: result => {
      console.log(this.msg + " deleteItem success", result);
      
      const nlist = this.familyList().filter(d => d.id !== id);
      this.familyList.set(nlist);    
       this.cdr.detectChanges();
      },
      error: e => console.error(e)
    });
    //console.log(this.msg + "click button to delete");
  }

  newFamily():void {
  //console.log("add new employee");
    this.personService.parentList = this.familyList();
  //  this.router.navigate( ['/family/new'], { queryParams: {returnUrl:'/family' } });
    this.showEdit(this._id--);
  }
  edit(id: number) : void {
    //console.log("edit family", id);
    this.personService.parentList = this.familyList();
   // this.router.navigate( ['/family/'+id], { queryParams: {returnUrl:'/family' } });
    this.showEdit(id);
  }
  showEdit(id:number) {
    const ref = this.dialogService.open(PersonEdit, {
      data: {
         id, 
         familyList: this.familyList(),         
    },
      header: 'Person',
      width: '80%',
      draggable: true,
      maximizable: true
    });
    
    ref.onClose.subscribe((item: Person) => {
      if (item) {
        //console.log("after close ward edit", item);
     //   this.messageService.add({severity:'success', summary: 'Save Family', detail: item.firstName!});
       //update the current list
        this.updateList(item);
      }
      });
   }

   showOrganise(id:number) {
    const ref = this.dialogService.open(FamilyOrga, {
      data: {
         id, 
         familyList: this.familyList(),         
    },
      header: 'Children',
      width: '80%',
      maximizable: true
    });
    
    ref.onClose.subscribe((item: Person) => {
      if (item) {
        //console.log("after close ward edit", item);
     //   this.messageService.add({severity:'success', summary: 'Save Family', detail: item.firstName!});
       //update the current list
        //this.updateList(item);
      }
      });
   }

   updateList(item: Person) :void {
    const list = this.familyList();
    const idx = list.findIndex( x => x.id === item.id);
    if (item.fatherId && item.fatherId > 0)
      item.fatherName = this.getName(item.fatherId);
      if (item.motherId && item.motherId > 0)
      item.motherName = this.getName(item.motherId);
    if (idx < 0)
    {      
      const olist = [... list, item];
      this.familyList.set(olist);
    }
    else
    {
      
      const oitem = list[idx];
      oitem.firstName = item.firstName;
      oitem.lastName = item.lastName;
      oitem.address = item.address;
      oitem.alive = item.alive;
      oitem.dob = item.dob;
      oitem.sex = item.sex;
      oitem.email = item.email;
      oitem.fatherId = item.fatherId;
      oitem.motherId = item.motherId;
      oitem.fatherName = item.fatherName;
      oitem.motherName = item.motherName;      
      this.familyList.set(list);
    }
    this.cdr.markForCheck();
   }
  
  
  ngOnDestroy() {
		this.subscription.unsubscribe();
	}
}

