import { EChartsOption } from 'echarts';
import { AppraisalSubordinateModel, Masfromevaluationassessment, TypeList } from 'src/app/shared/model/appraisal-subordinate.model';
import { AppraisalService } from 'src/app/shared/services/appraisal.service';
import { FileService } from 'src/app/shared/services/file.service';
import { environment } from 'src/environments/environment';
import Swal from 'sweetalert2';
import {
  Component,
  Input,
  Output,
  EventEmitter,
  ViewEncapsulation,
  OnInit,
  ViewChild,
  SimpleChanges,
  ChangeDetectorRef
} from '@angular/core';
import {
  EditService,
  SearchService,
  ReorderService,
  SortService,
  GroupService,
  ColumnMenuService,
  PageService,
  FilterService,
  SelectionSettingsModel,
  ToolbarItems,
  ToolbarService,
  GridComponent,
  PdfExportService,
  ExcelExportService,
  DetailRowService,
  DetailDataBoundEventArgs,
  Grid,
  AggregateService,
  PdfExportProperties,
  LoadingIndicatorModel,
  ExcelExportProperties,
  Column,
  ColumnMenuClickEventArgs
} from '@syncfusion/ej2-angular-grids';
import { GroupSettingsModel, FilterSettingsModel, ColumnModel } from '@syncfusion/ej2-angular-grids';
import { DataManager, Query } from '@syncfusion/ej2-data';
import { L10n, setCulture } from '@syncfusion/ej2-base';
import { TranslateService } from '@ngx-translate/core';
setCulture('th-TH');
@Component({
  selector: 'app-supervisor-evaluation',
  templateUrl: './supervisor-evaluation.component.html',
  styleUrls: ['./supervisor-evaluation.component.scss'],
  providers: [AggregateService, SortService, GroupService, ColumnMenuService, PageService, FilterService, ToolbarService, PdfExportService, ExcelExportService, DetailRowService, ReorderService, EditService, SearchService],
  encapsulation: ViewEncapsulation.None
})
export class SupervisorEvaluationComponent {
  pathTitle = ['การประเมินผล', 'ประเมินโดยหัวหน้า']
  pageEvalution = ''
  currentDate = new Date()
  subordinate: { loading: false, select?: AppraisalSubordinateModel, dataList: AppraisalSubordinateModel[] } = { loading: false, select: undefined, dataList: [] }
  search = ""
  currentPage = 1
  page = Array.from({ length: 1 }, (_, i) => i + 1)
  formEvaluation = {
    evaluateeId: "",
    evaluaterId: "",
    competencyTypeId: "",
    evaluationRoundId: "",
    allCompetencyTypeId: <TypeList[]>[],
    masfromStatusType: ""
  }
  selectEmp: Map<string, boolean> = new Map<string, boolean>()
  statusButtonClass = (status: string) => {
    if (status === "no access") {
      return "ti-btn-soft-mute"
    } else if (status === "pending") {
      return "ti-btn-soft-secondary"
    } else if (status === "evaluating") {
      return "ti-btn-soft-warning"
    } else if (status === "completed") {
      return "ti-btn-soft-success"
    } else if (status === "rejected") {
      return "ti-btn-soft-danger"
    } else {
      return ""
    }
  }
  statusCompetencyText = (status: string) => {
    if (status === "no access") {
      return "NotStarted"
    } else if (status === "pending") {
      return "Pending"
    } else if (status === "evaluating") {
      return "InProgress"
    } else if (status === "completed") {
      return "Completed"
    } else if (status === "rejected") {
      return "ส่งกลับ"
    } else {
      return ""
    }
  }


  subordinateApproveOption!: EChartsOption;
  subordinateApprovePer: number = 0
  myApproveOption!: EChartsOption;
  myApprovePer: number = 0
  pmsOption!: EChartsOption;

  syncfution: {
    dataList: any[],
    searchSettings: {
      fields: string[],
      operator: 'contains',
      ignoreCase: false
    },
    columns: ColumnModel[]
  } = {
      dataList: [],
      searchSettings: {
        fields: [
          'employeeId',
          'fullName',
          'position',
          'statusIdp',
          'sumScore',
          'grade',
          'apsapproveType'],
        operator: 'contains',
        ignoreCase: false
      },
      columns: []
    }

  @ViewChild('grid') public grid?: GridComponent;
  dataSourceSearch: any[] = [];
  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 };
  dataSourceFilter: any[] = [];
  aggregatesSum: any[] = [];
  aggregatesCount: any[] = [];
  aggregatesAvg: any[] = [];
  aggregatesMin: any[] = [];
  aggregatesMax: any[] = [];

  locale = 'th-TH'
  constructor(private appraisalService: AppraisalService,
    private fileService: FileService,
    private translateService: TranslateService,
    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' }
      ];
      if (this.subordinate.select?.showPms) {
        this.setSyncfutionDataList()
        this.searchDataGrid(this.search)
        this.cdr.markForCheck()
      }
    });
  }
  ngOnInit(): void {
    this.formEvaluation.evaluaterId = this.decodeJWT(sessionStorage.getItem("accessToken") || '').employeeid
    this.getBossList()


  }
  getBossList() {
    this.syncfution = {
      dataList: [],
      searchSettings: {
        fields: [
          'employeeId',
          'fullName',
          'position',
          'statusIdp',
          'sumScore',
          'grade',
          'apsapproveType'],
        operator: 'contains',
        ignoreCase: false
      },
      columns: []
    }
    this.appraisalService.getBossList().subscribe({
      next: async response => {
        this.subordinate.dataList = JSON.parse(JSON.stringify(response))
        this.cdr.markForCheck()
        if (this.subordinate.dataList.length) {
          this.subordinate.select = JSON.parse(JSON.stringify(this.subordinate.dataList[0]))
          this.setSyncfution()
          this.setEcharts()
        }
        const grid = await this.waitForGrid();
        if (grid) {
          this.searchDataGrid(this.search)
        }

        this.cdr.markForCheck()
      }, error: error => {
        this.cdr.markForCheck()
      }
    })
  }

  waitForGrid(): Promise<GridComponent> {
    return new Promise(resolve => {
      const check = () => {
        if (this.grid) resolve(this.grid);
        else setTimeout(check, 50); // ตรวจสอบซ้ำทุก 50ms
      };
      check();
    });
  }


  setSyncfution() {
    this.syncfution = {
      dataList: [],
      searchSettings: {
        fields: [
          'employeeId',
          'fullName',
          'position',
          'statusIdp',
          'sumScore',
          'grade',
          'apsapproveType'],
        operator: 'contains',
        ignoreCase: false
      },
      columns: []
    }
    if (this.subordinate.select?.showPms) {
      this.setSyncfutionDataList()
      this.syncfution.columns =
        [{
          field: "employeeId",
          headerText: "EmployeeCode",
          type: "string",
          isPrimaryKey: true,
        },
        {
          field: "fullName",
          headerText: "EmployeeName",
          type: "string"
        },
        {
          field: "position",
          headerText: "Position",
          type: "string"
        },
        {
          field: "statusType",
          headerText: "Status",
          type: "string"
        },
        {
          field: "sumScore",
          headerText: "Result",
          type: "string"
        },
        {
          field: "grade",
          headerText: "Grade",
          type: "string"
        },
        {
          field: "apsapproveType",
          headerText: "AppraiserStatus",
          type: "string"
        }]
    }
    this.cdr.markForCheck()
  }
  setSyncfutionDataList() {
    if (this.subordinate.select?.showPms) {
      this.syncfution.dataList = this.subordinate.select.masfromevaluationassessment.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),
        statusType: this.statusCompetencyText(e.statusIdp.statusType),
        statusIdp: e.statusIdp,
        sumScore: e.sumScore,
        grade: e.grade,
        apsapproveType: this.translateText(e.apsapproveType.tdesc, e.apsapproveType.edesc),
        apsassessy: e.apsassessy,
        masfromStatusType: e.masfromStatusType
      }))
      this.cdr.markForCheck()
    }
  }
  selectDataList(data?: AppraisalSubordinateModel) {
    this.selectEmp.clear()
    this.subordinate.select = JSON.parse(JSON.stringify(data))
    this.setSyncfutionDataList()
    this.setEcharts()
    this.searchDataGrid(this.search)
    this.cdr.markForCheck()
  }

  subordinateAll() {
    return this.subordinate.select?.masfromevaluationassessment.length || 0
  }
  subordinateRemain() {
    return this.subordinate.select?.masfromevaluationassessment.filter(e => e.masfromStatusType.code == 'no access').length || 0
  }
  subordinateApprove() {
    return this.subordinate.select?.masfromevaluationassessment.filter(e => e.masfromStatusType.code != 'no access').length || 0
  }
  myRemain() {
    return this.subordinate.select?.masfromevaluationassessment.filter(e => e.masfromStatusType.code != 'completed').length || 0
  }
  myApprove() {
    return this.subordinate.select?.masfromevaluationassessment.filter(e => e.masfromStatusType.code == 'completed').length || 0
  }
  gradeAll() {
    return this.subordinate.select?.masfromevaluationassessment.map(e => e.grade) || []
  }
  gradeFindLength(text: string) {
    return this.gradeAll().filter(x => x == text).length || 0
  }
  gradeFindPer(text: string) {
    return this.gradeAll().length > 0 ? Math.round((this.gradeFindLength(text) / this.gradeAll().length) * 100) : 0;
  }
  gradeColor(text: string) {
    if (text == 'A') return '#C084FC';
    if (text == 'B') return '#2563EB';
    if (text == 'C') return '#FB923C';
    if (text == 'D') return '#22C55E';
    if (text == 'E') return '#FEDDDE';
    return '';
  };
  setEcharts() {
    const full = this.subordinateAll()
    const remain = this.subordinateRemain()
    const approve = this.subordinateApprove()
    this.subordinateApprovePer = full > 0 ? Math.round((approve / full) * 100) : 0;
    this.subordinateApproveOption = {
      tooltip: {
        trigger: 'item',
        formatter: '{b}: {c} ({d}%)'
      },
      legend: {
        show: false
      },
      series: [
        {
          type: 'pie',
          radius: ['55%', '80%'],
          data: [
            {
              value: full - remain,
              itemStyle: { color: '#60A5FA' },
              name: 'ประเมินแล้ว',
            },
            {
              value: remain,
              itemStyle: { color: '#00000033' },
              name: 'ยังไม่ประเมิน',
            }
          ],
          label: {
            show: false
          },
          labelLine: {
            show: false
          }
        }
      ]
    };
    const myRemain = this.myRemain()
    const myApprove = this.myApprove()
    this.myApprovePer = full > 0 ? Math.round((myApprove / full) * 100) : 0;
    this.myApproveOption = {
      tooltip: {
        trigger: 'item',
        formatter: '{b}: {c} ({d}%)'
      },
      legend: {
        show: false
      },
      series: [
        {
          type: 'pie',
          radius: ['55%', '80%'],
          data: [
            {
              value: full - myRemain,
              itemStyle: { color: '#1DBE5A' },
              name: 'อนุมัติแล้ว',
            },
            {
              value: myRemain,
              itemStyle: { color: '#00000033' },
              name: 'ยังไม่อนุมัติ',
            }
          ],
          label: {
            show: false
          },
          labelLine: {
            show: false
          }
        }
      ]
    }
    this.subordinate.select?.masfromevaluationassessment.map(e => e.grade)
    const dataPms = this.gradeAll().filter(e => e).map(e => {
      return {
        value: this.gradeFindLength(e),
        itemStyle: { color: this.gradeColor(e) },
        name: 'Grade ' + e,
      }
    })
    this.pmsOption = {
      tooltip: {
        trigger: 'item',
        formatter: '{b}: {c} ({d}%)'
      },
      legend: {
        show: false
      },
      series: [
        {
          type: 'pie',
          radius: ['55%', '80%'],
          data: dataPms,
          label: {
            show: false
          },
          labelLine: {
            show: false
          }
        }
      ]
    };
  }



  selectSubordinate(data: Masfromevaluationassessment, competencyTypeId: string, evaluationRoundId?: string, masfromStatusType?: string) {
    if (data && evaluationRoundId) {
      this.formEvaluation.evaluateeId = data.apsassessy.employeeId
      this.formEvaluation.competencyTypeId = competencyTypeId
      this.formEvaluation.evaluationRoundId = evaluationRoundId
      this.formEvaluation.masfromStatusType = masfromStatusType || ''
      this.formEvaluation.allCompetencyTypeId = data.typeList
      this.cdr.markForCheck()
    }
  }

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

  toggleSelectAll() {
    if (this.dataSourceSearch.filter(e => e.apsapproveType.code != 'Apsapprove1' && (e.masfromStatusType.code == 'evaluating' || e.masfromStatusType.code == 'pending')).length > 0) {
      if (!this.selectEmp.get('selectAll')) {
        this.selectEmp.set('selectAll', true)
        this.dataSourceSearch.filter(e => e.apsapproveType.code != 'Apsapprove1' && (e.masfromStatusType.code == 'evaluating' || e.masfromStatusType.code == 'pending')).forEach(e => {
          this.selectEmp.set(e.apsassessy.employeeId, true)
        })
      } else {
        this.selectEmp.set('selectAll', false)
        this.selectEmp.clear()
      }
    }
  }

  checkSelectAll() {
    this.selectEmp.set('selectAll', (this.dataSourceSearch.filter(e => e.apsapproveType.code != 'Apsapprove1' &&
      (e.masfromStatusType.code == 'evaluating' || e.masfromStatusType.code == 'pending')).length > 0 &&
      this.dataSourceSearch.filter(e => e.apsapproveType.code != 'Apsapprove1' &&
        (e.masfromStatusType.code == 'evaluating' || e.masfromStatusType.code == 'pending')).length == this.selectEmp.size - 1))
  }
  postBossApproveAll() {
    if (this.subordinate.select) {
      Swal.fire({
        iconHtml: `
                    <div class="flex items-center justify-center rounded-full !h-80px !w-80px" style="background-color: #E8F8EE;">
                        <svg width="39" height="39" viewBox="0 0 39 39" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <rect width="39" height="39" fill="#D2D2D2"/>
                            <g id="Component">
                                <g id="alert cart">
                                    <g id="mdi:file-export">
                                        <circle cx="22.5" cy="19.5" r="33.5" fill="#E8F8EE"/>
                                        <path d="M9.75 3.25C8.88805 3.25 8.0614 3.59241 7.4519 4.2019C6.84241 4.8114 6.5 5.63805 6.5 6.5V32.5C6.5 33.362 6.84241 34.1886 7.4519 34.7981C8.0614 35.4076 8.88805 35.75 9.75 35.75H29.25C30.112 35.75 30.9386 35.4076 31.5481 34.7981C32.1576 34.1886 32.5 33.362 32.5 32.5V13L22.75 3.25M21.125 5.6875L30.0625 14.625H21.125M14.5113 19.8575H26V31.3463L22.555 27.9013L17.9563 32.5L13.3575 27.9013L17.9563 23.3188" 
                                        fill="#1DBE5A"/>
                                    </g>
                                </g>
                            </g>
                        </svg>
                    </div>
                    `,
        title: 'อนุมัติ',
        text: 'คุณต้องการยืนยันการอนุมัตินี้ใช่หรือไม่',
        showCancelButton: true,
        confirmButtonText: 'ยืนยันการอนุมัติ',
        cancelButtonText: 'ย้อนกลับ',
        customClass: {
          title: '!swal2-title-mt-20px',
          actions: '!swal2-actions-mt-20px',
          icon: '!swal2-icon-no-border',
          confirmButton: '!swal2-button-bg-green',
          cancelButton: '!swal2-button-bg-gray',
        },
      }).then((result) => {
        if (result.isConfirmed) {
          const body = {
            masFromEvaluationRoundId: this.subordinate.select!.evaluationRoundId,
            employeeId: Array.from(this.selectEmp.entries())
              .filter(([_, value]) => value)
              .map(([key]) => key).filter(e => e != 'selectAll')
          }
          this.appraisalService.postBossApproveAll(body).subscribe(response => {
            if (response.success) {
              this.selectEmp.clear()
              this.getBossList()
              Swal.fire({
                title: 'บันทึกสำเร็จ!',
                text: 'การอนุมัติของคุณถูกบันทึกแล้ว',
                icon: 'success',
                customClass: {
                  confirmButton: '!swal2-button-bg-green',
                }
              });
            } else {
              Swal.fire({
                title: 'ยกเลิก!',
                text: 'การอนุมัติถูกยกเลิก',
                icon: 'error',
                customClass: {
                  confirmButton: '!swal2-button-bg-danger',
                }
              });
            }
          })
        } else if (result.dismiss === Swal.DismissReason.cancel) {
          Swal.fire({
            title: 'ยกเลิก!',
            text: 'การอนุมัติถูกยกเลิก',
            icon: 'error',
            customClass: {
              confirmButton: '!swal2-button-bg-danger',
            }
          })
        }
      })
    }
  }

  getImg(text: string) {
    return this.fileService.getImg(text)
  }

  onImageError(event: Event) {
    const imgElement = event.target as HTMLImageElement;
    imgElement.src = './assets/img/users/defaultperson.jpg';
  }

  searchDataGrid(text: string) {
    if (this.grid) {
      if (this.syncfution.searchSettings.fields.length) {
        this.dataSourceSearch = JSON.parse(JSON.stringify(this.filterData(text, this.syncfution.searchSettings.fields)));
        this.dataSourceFilter = JSON.parse(JSON.stringify(this.filterData(text, this.syncfution.searchSettings.fields)));
      } else {
        (this.grid as GridComponent).search(text);
      }
    }
    this.checkSelectAll()
  }

  filterData(text: string, fields: string[]): any[] {
    return this.syncfution.dataList.filter(item => {
      return fields.some(field => {
        const value = field.split('.').reduce((obj, key) => obj?.[key], item);
        return value?.toString().toLowerCase().includes(text.toLowerCase());
      }
      );
    });
  }


  actionComplete(args: any) {
    if (args.requestType === 'filtering') {
      if (this.grid) {
        this.dataSourceFilter = ((this.grid as GridComponent).getFilteredRecords() as any).length ? ((this.grid as GridComponent).getFilteredRecords() as any) : JSON.parse(JSON.stringify(this.dataSourceSearch || []));
      }
    }
  }
  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)
    }
  }

  checkSubordinate(employeeId: string) {
    return this.subordinate.select?.masfromevaluationassessment.find(x => x.apsassessy.employeeId == employeeId)
  }

  translateText(th?: string, en?: string) {
    return this.translateService.getCurrentLang() == 'th' ? (th || '') : (en || '')
  }
}
