import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, SimpleChanges, ViewChild } from "@angular/core";
import { MatDialog, MatDialogRef } from "@angular/material/dialog";
import { Router, ActivatedRoute } from "@angular/router";
import { TranslateService } from "@ngx-translate/core";
import { AppraisalKpiSettingEmpModel, MyAppraisalKpiSettingEmpModel, MyPmsTypeModel, MyTopicModel, PmsTypeModel, TopicModel } from "src/app/shared/model/appraisal-kpi-setting-emp.model";
import { EmployeeModel, MyEmployeeModel } from "src/app/shared/model/employee.model";
import { AppraisalService } from "src/app/shared/services/appraisal.service";
import { EmployeeService } from "src/app/shared/services/employee.service";
import { FileService } from "src/app/shared/services/file.service";
import { PmstypeService } from "src/app/shared/services/pmstype.service";
import { TokenService } from "src/app/shared/services/token.service";
import { ToastrService } from 'ngx-toastr';
import Swal from 'sweetalert2';
import { AggregateService, Column, ColumnMenuClickEventArgs, ColumnMenuService, ColumnModel, DetailRowService, EditService, ExcelExportProperties, ExcelExportService, FilterService, FilterSettingsModel, GridComponent, GroupService, GroupSettingsModel, LoadingIndicatorModel, PageService, PdfExportService, ReorderService, SearchService, SelectionSettingsModel, SortService, ToolbarService } from "@syncfusion/ej2-angular-grids";
import { Query } from '@syncfusion/ej2-data';
import { setCulture } from '@syncfusion/ej2-base';
@Component({
  selector: 'app-evaluation-confirmation',
  templateUrl: './evaluation-confirmation.component.html',
  providers: [AggregateService, SortService, GroupService, ColumnMenuService, PageService, FilterService, ToolbarService, PdfExportService, ExcelExportService, DetailRowService, ReorderService, EditService, SearchService],
  styleUrls: ['./evaluation-confirmation.component.scss']
})
export class EvaluationConfirmationComponent {
  page = 1
  search = ''
  syncfution: {
    dataList: any[],
    searchSettings: {
      fields: string[],
      operator: 'contains',
      ignoreCase: false
    },
    columns: ColumnModel[]
  } = {
      dataList: [],
      searchSettings: {
        fields: [
          'round',
          'year',
          'status'],
        operator: 'contains',
        ignoreCase: false
      },
      columns: [{
        field: "round",
        headerText: "Evaluation Period",
        type: "string",
        isPrimaryKey: true,
      },
      {
        field: "year",
        headerText: "Year",
        type: "string"
      },
      {
        field: "status",
        headerText: "Status",
        type: "string"
      }]
    }
  @ViewChild('grid') public grid?: GridComponent;
  filterSettings: FilterSettingsModel = { type: 'Excel' };
  selectionOptions: SelectionSettingsModel = { checkboxOnly: true };
  groupSettings: GroupSettingsModel = { allowReordering: true, showGroupedColumn: true, showDropArea: false };
  toolbarOptions: any[] = ['Print', 'ExcelExport', 'CsvExport'];
  editSettings? = { allowEditing: true, mode: 'Batch' };
  loadingIndicator: LoadingIndicatorModel = { indicatorType: 'Shimmer' };
  query: Query = new Query().addParams('dataCount', '1000');
  columnMenuItems: any[] = [
    'AutoFit', 'AutoFitAll', 'SortAscending', 'SortDescending',
    'Group', 'Ungroup', 'ColumnChooser', 'Filter',
    { text: 'Sum', id: 'aggregate_sum' },
    { text: 'Count', id: 'aggregate_count' },
    { text: 'Average', id: 'aggregate_average' },
    { text: 'Min', id: 'aggregate_min' },
    { text: 'Max', id: 'aggregate_max' }
  ];
  initialPage? = { pageSizes: true, pageSize: 10 };
  aggregatesSum: any[] = [];
  aggregatesCount: any[] = [];
  aggregatesAvg: any[] = [];
  aggregatesMin: any[] = [];
  aggregatesMax: any[] = [];
  locale = 'th-TH'

  @ViewChild('employeeDialog') employeeDialog: any
  employeeDialogRef: any
  evaluaterId = ''
  constructor(private appraisalService: AppraisalService,
    private fileService: FileService,
    private translateService: TranslateService,
    private tokenService: TokenService,
    private dialog: MatDialog,
    private cdr: ChangeDetectorRef) {

    this.locale = this.translateService.getCurrentLang() == 'th' ? 'th-TH' : 'en-US'

    this.translateService.onLangChange.subscribe((event) => {
      if (event.lang === 'th') {
        setCulture('th-TH');
        this.locale = 'th-TH'
      } else if (event.lang === 'en') {
        setCulture('en-US');
        this.locale = 'en-US'
      }
      this.toolbarOptions = [
        { text: this.translateService.instant('Print'), prefixIcon: 'e-print', id: 'Print' },
        { text: this.translateService.instant('ExcelExport'), prefixIcon: 'e-excelexport', id: 'ExcelExport' },
        { text: this.translateService.instant('CSVExport'), prefixIcon: 'e-csvexport', id: 'CsvExport' }
      ]
      this.setSyncfutionDataList()
      this.cdr.markForCheck()
    });
  }
  ngOnInit(): void {
    this.evaluaterId = this.decodeJWT(sessionStorage.getItem("accessToken") || '').employeeid
    this.getEmpKpi()
  }

  decodeJWT(token: string) {
    let base64Url = token.split('.')[1];
    let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
    return JSON.parse(jsonPayload);
  }


  openEmployeeDialog() {
    this.employeeDialogRef = this.dialog.open(this.employeeDialog, {
      width: '1000px',
    })
  }
  closeEmployeeDialog() {
    this.employeeDialogRef.close()
  }


  getEmpKpi() {
    this.syncfution.dataList = []
    this.setSyncfutionDataList()
    // this.appraisalService.getEmpKpi().subscribe({
    //   next: response => {
    //     this.subordinate.dataList = response.map(e => new MyAppraisalKpiSettingModel(e))
    //     this.setSyncfutionDataList()
    //     this.cdr.markForCheck()
    //   }, error: error => {
    //     this.cdr.markForCheck()
    //   }
    // })
  }

  setSyncfutionDataList() {
    // this.syncfution.dataList = this.subordinateFilter().map(e => ({
    //   employeeId: e.apsassessy.employeeId,
    //   fullName: this.translateText(e.apsassessy.thFullName, e.apsassessy.engFullName),
    //   position: this.translateText(e.apsassessy.position.tdesc, e.apsassessy.position.edesc),
    //   status: this.translateText(e.statusApprove.tdesc, e.statusApprove.edesc),
    //   statusCode: e.statusApprove.code,
    //   statusEdesc: e.statusApprove.edesc,
    //   picture: e.apsassessy.picture
    // }))
    this.syncfution.dataList = this.dataFilter().map(e => ({
      round: e,
      year: e,
      status: e
    }))
  }

  dataFilter() {
    return [1, 2, 3, 4].filter(x => {
      return (x + '').toLowerCase().includes(this.search.toLowerCase())
    })
  }

  onColumnMenuClick(args: ColumnMenuClickEventArgs): void {
    if (!args.item.id) { return; }
    if (args.item.id.startsWith('aggregate_')) {
      const colField = (args.column as any)?.field;
      if (!colField) { return; }
      const selectedAgg = args.item.id.split('_')[1];
      if (selectedAgg === 'sum') {
        if (this.aggregatesSum.find(a => a.field === colField)) {
          this.aggregatesSum = this.aggregatesSum.filter(a => a.field !== colField);
        } else {
          this.aggregatesSum.push({
            field: colField,
            type: 'Sum',
            footerTemplate: 'Sum: ${Sum}'
          });
        }
        this.cdr.markForCheck()
      }
      else if (selectedAgg === 'count') {
        this.aggregatesCount.push({
          field: colField,
          type: 'Count',
          footerTemplate: 'Count: ${Count}'
        });
      } else if (selectedAgg === 'average') {
        this.aggregatesAvg.push({
          field: colField,
          type: 'Average',
          footerTemplate: 'Avg: ${Average}'
        });
      }
      else if (selectedAgg === 'min') {
        this.aggregatesMin.push({
          field: colField,
          type: 'Min',
          footerTemplate: 'Min: ${Min}'
        });
      }
      else if (selectedAgg === 'max') {
        this.aggregatesMax.push({
          field: colField,
          type: 'Max',
          footerTemplate: 'Max: ${Max}'
        });
      }
      setTimeout(() => {
        this.grid?.refresh();
      }, 500);
    }
  }

  toolbarClick(args: any): void {
    if (args.item.id === 'Grid_excelexport') {
      let exportProperties: ExcelExportProperties = {
        columns: this.syncfution.columns.map(col => ({
          field: col.field,
          headerText: col.headerText
        })) as Column[]
      };
      this.grid?.excelExport(exportProperties);
    } else if (args.item.id === 'Grid_csvexport') {
      let exportColumns = this.syncfution.columns.map(col => ({
        field: col.field || '',
        headerText: col.headerText || ''
      }));
      this.grid?.csvExport({ columns: exportColumns as Column[] });
    } else if (args.item.id === 'Grid_print') {
      this.cdr.markForCheck()
      setTimeout(() => {
        this.cdr.markForCheck()
      }, 1000)
    }
  }

  @ViewChild('pdfArea') pdfArea!: ElementRef<HTMLElement>;

  async exportPdf() {
    const el = this.pdfArea?.nativeElement;
    if (!el) return;

    // 👉 ลบ shadow ออกจากทุก element ที่มี shadow class
    const shadowEls = el.querySelectorAll('.shadow');
    shadowEls.forEach(e => e.classList.remove('shadow'));

    const mod: any = await import('html2pdf.js');
    const html2pdf = mod.default ?? mod;

    const cleanupScale = this.expandToFullWidthThenScale(el);
    const cleanupUnclip = this.unclipOverflows(el);

    const prevBodyOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';

    const fullW = el.scrollWidth;
    const fullH = el.scrollHeight;
    const epsilon = 2;

    console.log('🥷🏿Math.max(0, fullH - epsilon) --->', Math.max(0, fullH - epsilon));
    const opt = {
      margin: [10, 10, 10, 10],
      filename: `test.pdf`,
      image: { type: 'jpeg', quality: 0.96 },
      html2canvas: {
        scale: 2,
        useCORS: true,
        logging: false,
        scrollX: 0,
        scrollY: -window.scrollY,
        width: 794,
        // height: Math.max(0, fullH - epsilon),
        height: 1123,
        windowWidth: 794,
        // windowHeight: Math.max(0, fullH - epsilon),
        windowHeight: 1123,
      },
      jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
      pagebreak: { mode: ['css', 'legacy'], avoid: ['.no-break', 'table', 'img'] },
      onclone: (doc: any) => {
        doc.querySelectorAll('[data-hide-in-pdf]').forEach((el: any) => el.remove());
      },
    };

    try {
      await html2pdf().from(el).set(opt).save();
    } finally {
      cleanupUnclip();
      cleanupScale();
      document.body.style.overflow = prevBodyOverflow;

      // 👉 คืน class shadow กลับ
      shadowEls.forEach(e => e.classList.add('shadow'));
    }
  }

  expandToFullWidthThenScale(el: HTMLElement) {
    const A4_PX = 794; // ≈ 210mm @ 96dpi
    const full = el.scrollWidth;               // ความกว้างจริงทั้งหมด (รวมพื้นที่ต้องเลื่อนขวา)
    const scale = Math.min(1, A4_PX / full);   // สเกลลงให้พอดี A4 (ถ้ากว้างกว่า)

    // เก็บค่าเดิมไว้คืนทีหลัง
    const prev = {
      width: el.style.width,
      maxWidth: el.style.maxWidth,
      overflowX: el.style.overflowX,
      transform: el.style.transform,
      transformOrigin: el.style.transformOrigin,
    };

    // คลี่ความกว้างออกทั้งหมด แล้วสเกลให้พอดี A4
    el.style.width = `${full}px`;
    el.style.maxWidth = 'none';
    el.style.overflowX = 'visible';
    el.style.transformOrigin = 'top left';
    el.style.transform = `scale(${scale})`;

    // คืนค่า
    return () => {
      el.style.width = prev.width;
      el.style.maxWidth = prev.maxWidth;
      el.style.overflowX = prev.overflowX;
      el.style.transform = prev.transform;
      el.style.transformOrigin = prev.transformOrigin;
    };
  }

  private unclipOverflows(el: HTMLElement) {
    const patched: Array<{ node: HTMLElement, prev: Partial<CSSStyleDeclaration> }> = [];
    const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);

    const patchNode = (node: HTMLElement) => {
      const style = window.getComputedStyle(node);
      const needOverflowPatch = style.overflowX !== 'visible' || style.overflow !== 'visible';
      const isSticky = style.position === 'sticky';

      if (needOverflowPatch || isSticky) {
        const prev = {
          overflow: node.style.overflow,
          overflowX: node.style.overflowX,
          overflowY: node.style.overflowY,
          position: node.style.position,
          clipPath: (node.style as any).clipPath,
        };
        patched.push({ node, prev });

        node.style.overflow = 'visible';
        node.style.overflowX = 'visible';
        node.style.overflowY = 'visible';
        if (isSticky) node.style.position = 'static';
        (node.style as any).clipPath = 'none';
      }
    };

    // รวม el เองด้วย
    patchNode(el as HTMLElement);
    while (walker.nextNode()) {
      patchNode(walker.currentNode as HTMLElement);
    }

    // ฟังก์ชันคืนค่าเดิม
    return () => {
      for (const { node, prev } of patched) {
        node.style.overflow = prev.overflow || '';
        node.style.overflowX = prev.overflowX || '';
        node.style.overflowY = prev.overflowY || '';
        node.style.position = prev.position || '';
        (node.style as any).clipPath = prev.clipPath || '';
      }
    };
  }




  save() {
    Swal.fire({
      icon: 'question',
      title: 'แจ้งเตือน',
      text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
      showCancelButton: true,
      confirmButtonText: 'บันทึกข้อมูล',
      cancelButtonText: 'ย้อนกลับ',
      reverseButtons: true,
    }).then((result) => {
      if (result.isConfirmed) {
        this.showAlert('บันทึกข้อมูลสำเร็จ', 'success')
        this.closeEmployeeDialog();
      }
    });
  }

  showAlert(text: string, type: 'success' | 'error') {
    Swal.fire({
      title: 'แจ้งเตือน',
      text: text,
      icon: type,
      confirmButtonText: 'ตกลง',
    });
  }

}


