import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { CompetencyModel, Pms } from 'src/app/shared/model/competency.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 { TokenService } from 'src/app/shared/services/token.service';
import Swal from 'sweetalert2';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { environment } from 'src/environments/environment';
import { FileService } from 'src/app/shared/services/file.service';

@Component({
  selector: 'app-pms-form-employee',
  templateUrl: './pms-form-employee.component.html',
  styleUrls: ['./pms-form-employee.component.scss']
})
export class PmsFormEmployeeComponent {
  @Input() currentTap = "ข้อมูลการประเมิน"
  firstCurrentTap = ""
  @Input() evaluateeId = ""
  @Input() evaluaterId = ""
  @Input() evaluationForm: 'self' | 'sup' = "self"
  evaluatee: { loading: boolean, data: EmployeeModel } = { loading: false, data: new MyEmployeeModel() }
  currentPart = ""
  @Output() sendReturnPath: EventEmitter<any> = new EventEmitter<any>();
  starRate = 5;
  url1 = '';

  url2 = '';
  selectedItems = [];
  dropdownSettings = {};
  datePickerConfig = {
    format: 'DD-MM-YY',
  };

  dropdownList = [
    { id: '1', itemName: 'Laravel' },
    { id: '2', itemName: 'Angular' },
    { id: '3', itemName: 'HTML' },
    { id: '4', itemName: 'React' },
    { id: '5', itemName: 'Bootstrap' },
  ];

  compentency: { loading: boolean, originalData?: CompetencyModel, data?: CompetencyModel, dataList: CompetencyModel[] } = { loading: false, data: undefined, dataList: [] }
  canSave = false
  canEdit = false
  canDraft = false
  dateIso = ""
  compentencyFormRemain: number = 0
  kpiFormRemain: number = 0
  currentDate = new Date()
  comment = ""

  compentencyScoreBoss: String[] = []
  compentencyWeightScoreBoss = ""
  compentencyWeightTotalBoss = ""
  compentencyGapBoss = ""
  compentencyScore: String[] = []
  compentencyWeightTotal = ""
  compentencyWeightScore = ""
  compentencyGap = ""

  inforWeightBoss: Map<string, string> = new Map<string, string>()
  inforGapBoss: Map<string, string> = new Map<string, string>()
  inforWeight: Map<string, string> = new Map<string, string>()
  inforGap: Map<string, string> = new Map<string, string>()

  kpiScorePartBoss: { text: string, score: string }[] = []
  kpiScorePart: { text: string, score: string }[] = []

  menuClose: Map<string, boolean> = new Map<string, boolean>()

  hasPushedState = false;
  companyId = ""

  complete = false
  @ViewChild('scrollContainer') scrollContainer!: ElementRef;

  menuList: string[] = ['ข้อมูลการประเมิน', 'แบบประเมินสมรรถนะ', 'ประเมินผลการปฏิบัติงาน', 'สรุปคะแนนและข้อเสนอแนะ', 'แผนพัฒนาบุคลากร']

  constructor(
    private router: Router,
    private employeeService: EmployeeService,
    private appraisalService: AppraisalService,
    private cdr: ChangeDetectorRef,
    private tokenService: TokenService,
    private route: ActivatedRoute,
    private fileService: FileService
  ) {
  }

  findMenu(text: string) {
    return this.menuList.find(e => e == text)
  }

  currentStepText = () => {
    if (this.compentency.data) {
      if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) {
        return "ผู้รับการประเมิน"
      } else if (this.compentency.data.apsapprove1.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 1"
      } else if (this.compentency.data.apsapprove2.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 2"
      } else if (this.compentency.data.apsapprove3.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 3"
      } else if (this.compentency.data.apsapprove4.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 4"
      } else if (this.compentency.data.apsapprove5.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 5"
      }
    }
    return ""
  }
  currentStepTextShow = () => {
    if (this.compentency.data) {
      if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) {
        return "ผู้ประเมิน"
      } else if (this.compentency.data.apsapprove1.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 1"
      } else if (this.compentency.data.apsapprove2.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 2"
      } else if (this.compentency.data.apsapprove3.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 3"
      } else if (this.compentency.data.apsapprove4.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 4"
      } else if (this.compentency.data.apsapprove5.employeeId == this.evaluaterId) {
        return "ผู้อนุมัติลำดับที่ 5"
      }
    }
    return ""
  }

  gradeStar = (grade: string) => {
    if (grade == 'A') {
      return 5
    } else if (grade == 'B') {
      return 4
    } else if (grade == 'C') {
      return 3
    } else if (grade == 'D') {
      return 2
    } else if (grade == 'E') {
      return 1
    }
    return 0
  }

  statusCompetencyText = (status: string) => {
    if (status === "no access") {
      return "ยังไม่ถึงขั้นตอนดำเนินการ"
    } else if (status === "pending") {
      return "รอดำเนินการ"
    } else if (status === "evaluating") {
      return "อยู่ระหว่างดำเนินการ"
    } else if (status === "completed") {
      return "ดำเนินการเสร็จสิ้น"
    } else if (status === "rejected") {
      return "ส่งกลับ"
    } else {
      return ""
    }
  }
  statusCompetencyClass = (status: string) => {
    if (status === "no access") {
      return "bg-mute"
    } else if (status === "pending") {
      return "bg-secondary"
    } else if (status === "evaluating") {
      return "bg-warning"
    } else if (status === "completed") {
      return "bg-success"
    } else if (status === "rejected") {
      return "bg-danger"
    } else {
      return ""
    }
  }
  statusCompetencyIcon = (status: string) => {
    if (status === "no access") {
      return "ti ti-dots"
    } else if (status === "pending") {
      return "ti ti-clock"
    } else if (status === "evaluating") {
      return "ri-draft-fill"
    } else if (status === "completed") {
      return "ti ti-check"
    } else if (status === "rejected") {
      return "ri-reply-fill"
    } else {
      return ""
    }
  }
  assessmentStatusText = (currentStep: string, step: number, status: string) => {
    if (+currentStep < step) {
      if (status != '3') {
        return this.statusCompetencyText("no access")
      } else {
        return this.statusCompetencyText("rejected")
      }
    } else if (+currentStep >= step) {
      if (status == '0') {
        return this.statusCompetencyText("pending")
      } else if (status == '1') {
        return this.statusCompetencyText("evaluating")
      } else if (status == '2') {
        return this.statusCompetencyText("completed")
      } else {
        return ""
      }
    } else {
      return ""
    }
  }
  assessmentStatusClass = (currentStep: string, step: number, status: string) => {
    if (+currentStep < step) {
      if (status != '3') {
        return this.statusCompetencyClass("no access")
      } else {
        return this.statusCompetencyClass("rejected")
      }
    } else if (+currentStep >= step) {
      if (status == '0') {
        return this.statusCompetencyClass("pending")
      } else if (status == '1') {
        return this.statusCompetencyClass("evaluating")
      } else if (status == '2') {
        return this.statusCompetencyClass("completed")
      } else {
        return ""
      }
    } else {
      return ""
    }
  }
  assessmentStatusIcon = (currentStep: string, step: number, status: string) => {
    if (+currentStep < step) {
      if (status != '3') {
        return this.statusCompetencyIcon("no access")
      } else {
        return this.statusCompetencyIcon("rejected")
      }
    } else if (+currentStep >= step) {
      if (status == '0') {
        return this.statusCompetencyIcon("pending")
      } else if (status == '1') {
        return this.statusCompetencyIcon("evaluating")
      } else if (status == '2') {
        return this.statusCompetencyIcon("completed")
      } else {
        return ""
      }
    } else {
      return ""
    }
  }
  convertDate = (dateInput?: string | Date): string => {
    if (!dateInput) return '';
    let date: Date;
    if (typeof dateInput === 'string') {
      // ถ้าเป็น ISO string ที่มี T เช่น "2025-04-30T00:00:00Z"
      if (dateInput.includes('T')) {
        date = new Date(dateInput);
      } else {
        // ถ้าเป็น 'YYYY-MM-DD' (ไม่มี T)
        const [year, month, day] = dateInput.split('-').map(Number);
        date = new Date(year, month - 1, day);
      }
    } else {
      date = dateInput;
    }
    // ตรวจสอบว่า date ถูกต้อง (valid date)
    if (isNaN(date.getTime())) return '';

    return date.toLocaleDateString('th-TH', {
      weekday: 'short',
      day: 'numeric',
      month: 'short',
      year: 'numeric'
    });
  };
  handleBack = (event: PopStateEvent) => {
    this.returnPath()
    this.router.navigate(['/supervisor-evaluation']);
  };

  ngOnDestroy() {
    window.removeEventListener('popstate', this.handleBack);

  }

  ngOnInit() {
    this.route.paramMap.subscribe((params: ParamMap) => {
      if (params.get('part') == 'IDP') {
        this.firstCurrentTap = 'แผนพัฒนาบุคลากร'
      }
    });
    this.companyId = this.tokenService.getUser()?.companyid || ""
    this.dateIso = this.currentDate.toISOString();
    this.getEvaluatee()
    this.getCompentencyAll()
    // ดัน state ปลอมเข้าไปใน stack
    if (this.evaluationForm == 'sup') {
      if (!this.hasPushedState) {
        history.pushState(null, '', location.href);
        this.hasPushedState = true;
      }
      window.addEventListener('popstate', this.handleBack);
    }
  }

  getCompentencyAll() {
    this.compentency.loading = true
    const bossId = this.evaluaterId != this.evaluateeId ? this.evaluaterId : undefined
    this.appraisalService.getCompentencyAll(this.evaluateeId, bossId).subscribe({
      next: response => {
        this.compentency.dataList = response
        if (this.compentency.dataList.length) {
          this.selectDataList(this.compentency.dataList[0])
        }
        this.compentency.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.compentency.loading = false
        this.cdr.detectChanges()
      }
    })
  }

  selectDataList(data: CompetencyModel) {
    this.compentency.originalData = this.deepClone(data)
    this.compentency.data = this.deepClone(data)
    const checkMenu = Array.from({ length: 7 }, (_, i) => i + 1)
      .filter(i => (this.compentency.data?.pms?.[`part${i}Detail` as keyof Pms] as any)?.length).length
    if (!checkMenu) {
      this.menuList.splice(2, 1)
    }
    this.complete = this.compentency.data?.statusType == 'complete'
    this.cdr.detectChanges()
    if (this.compentency.data) {
      this.currentTap = this.firstCurrentTap || "ข้อมูลการประเมิน"
      this.firstCurrentTap = ''
      this.compentency.data.commentAll.sort((a, b) => new Date(b.commentDate).getTime() - new Date(a.commentDate).getTime());
      this.canSave = this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating"
      this.canDraft = +this.compentency.data.currentStep <= 1 && (this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating")
      this.canEdit = +this.compentency.data.currentStep <= 1 && (this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating")
      this.cdr.detectChanges()
    }
  }

  getEvaluatee() {
    this.evaluatee.loading = true
    this.employeeService.getWorkingById(this.evaluateeId).subscribe({
      next: response => {
        this.evaluatee.data = new MyEmployeeModel(response)
        this.evaluatee.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.evaluatee.loading = false
        this.cdr.detectChanges()
      }
    })
  }


  onSelectFile1(event: any) {
    if (event.target && event.target.files && event.target.files[0]) {
      const reader = new FileReader();
      reader.readAsDataURL(event.target.files[0]);
      reader.onload = (event: any) => {
        this.url1 = event.target.result;
      };
    }
  }

  onSelectFile2(event: any) {
    if (event.target && event.target.files && event.target.files[0]) {
      const reader = new FileReader();
      reader.readAsDataURL(event.target.files[0]);
      reader.onload = (event: any) => {
        this.url2 = event.target.result;
      };
    }
  }

  updateFormat() {
    this.datePickerConfig = {
      ...this.datePickerConfig,
      format: 'DD-MM-YY',
    };
  }

  returnPath() {
    this.sendReturnPath.emit()
  }

  commentAllFilter() {
    return this.compentency.data?.commentAll.filter(x => x.statusType == 'reject' ? x.createdBy == this.evaluaterId : x) || []
  }

  returnField(data: any, field: string): any {
    return field.split('.').reduce((obj, key) => obj?.[key], data);
  }



  save(status: 'approve' | 'noApprove' | 'draft') {
    if (this.compentency.data) {
      let title = ''
      let text = ''
      let confirmButtonText = ''
      let approveStatus = '0'
      if (status == 'draft') {
        approveStatus = '1'
        title = 'บันทึกแบบร่าง'
        text = 'คุณต้องการบันทึกแบบร่างของการประเมินนี้ใช่หรือไม่'
        confirmButtonText = 'ยืนยันการบันทึก'
      } else if (status == 'approve') {
        approveStatus = '2'
        if (this.compentency.data.currentStep == '0') {
          title = 'ยืนยันข้อมูล'
          text = 'คุณต้องการยืนยันข้อมูลการประเมินนี้ใช่หรือไม่'
          confirmButtonText = 'ยืนยันการบันทึก'
        } else {
          title == 'อนุมัติ'
          text = 'คุณต้องการอนุมัติข้อมูลการประเมินนี้ใช่หรือไม่'
          confirmButtonText = 'ยืนยันการอนุมัติ'
        }
      } else if (status == 'noApprove') {
        approveStatus = '3'
        title == 'ไม่อนุมัติ'
        text = 'คุณต้องการไม่อนุมัติข้อมูลการประเมินนี้ใช่หรือไม่'
        confirmButtonText = 'ยืนยันการไม่อนุมัติ'
      }
      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: title,
        text: text,
        showCancelButton: true,
        confirmButtonText: 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) {
          this.saveApi(approveStatus)
        } else if (result.dismiss === Swal.DismissReason.cancel) {
          Swal.fire({
            title: 'ยกเลิก!',
            text: 'การบันทึกถูกยกเลิก',
            icon: 'error',
            customClass: {
              confirmButton: '!swal2-button-bg-danger',
            }
          })
        }
      })
    }
  }
  saveApi(approveStatus: string) {
    if (this.compentency.data) {
      type StepKey = 'apsassessy' | 'apsapprove1' | 'apsapprove2' | 'apsapprove3' | 'apsapprove4' | 'apsapprove5';
      const steps: StepKey[] = ['apsassessy', 'apsapprove1', 'apsapprove2', 'apsapprove3', 'apsapprove4', 'apsapprove5'];
      const stepIndex = parseInt(this.compentency.data.currentStep, 10);
      const updatedData = this.deepClone(this.compentency.data)
      if (approveStatus === '3' && stepIndex >= 2) {
        const prevKey: StepKey = steps[stepIndex - 1];
        updatedData[prevKey] = {
          ...updatedData[prevKey],
          status: '0',
          stepReturn: stepIndex
        };
      }
      const currentKey: StepKey = steps[stepIndex];
      updatedData[currentKey] = {
        ...updatedData[currentKey],
        status: approveStatus,
      };
      updatedData.commentAll = this.compentency.data.commentAll

      let statusType = ""
      if (approveStatus === "1") {
        statusType = "evaluating"
      } else if (approveStatus === "2") {
        statusType = "completed"
        for (let i = stepIndex + 1; i < steps.length; i++) {
          const nextKey: StepKey = steps[i];
          if (updatedData[nextKey]?.status === '3') {
            updatedData[nextKey] = {
              ...updatedData[nextKey],
              status: '0',
            };
          }
        }
      } else if (approveStatus === "3") {
        statusType = "rejected"
      }
      updatedData.commentAll.push({
        commentDate: this.dateIso,
        companyId: this.companyId,
        currentStep: this.compentency.data.currentStep,
        statusType: statusType,
        comment: this.comment,
        createdBy: updatedData[currentKey].employeeId,
        thFullName: updatedData[currentKey].thFullName,
        engFullName: updatedData[currentKey].enFullName,
      })
      const body = updatedData;
      this.appraisalService.postCompentencyAll(body).subscribe({
        next: response => {
          if (response.success) {
            this.getCompentencyAll()
            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',
              }
            });
          }
        }, error: error => {
          Swal.fire({
            title: 'ยกเลิก!',
            text: 'การบันทึกถูกยกเลิก',
            icon: 'error',
            customClass: {
              confirmButton: '!swal2-button-bg-danger',
            }
          });
        }
      })
    }
  }

  showNumber(text: number | string) {
    const num = Number(text);
    return isNaN(num) ? 0 : +(+num.toFixed(2));
  }

  calWeightScore(weightScore: number) {
    switch (weightScore) {
      case (1): {
        return 1
      }
      case (2): {
        return 2
      }
      case (3): {
        return 3
      }
      case (4): {
        return 4
      }
      case (5): {
        return 5
      }
      default: { return }
    }
  }

  changeForm(item: CompetencyModel) {
    const ignorePart = [
      'competency',
      '!competency[].apsassessy',
      '!competency[].apsapprove1',
      '!competency[].apsapprove2',
      '!competency[].apsapprove3',
      '!competency[].apsapprove4',
      '!competency[].apsapprove5',
      '!competency[].masfromEvaluationAssessment1List[].apsassessyDate',
      '!competency[].masfromEvaluationAssessment1List[].apsapprove1Date',
      '!competency[].masfromEvaluationAssessment1List[].apsapprove2Date',
      '!competency[].masfromEvaluationAssessment1List[].apsapprove3Date',
      '!competency[].masfromEvaluationAssessment1List[].apsapprove4Date',
      '!competency[].masfromEvaluationAssessment1List[].apsapprove5Date',
      '!competency[].masfromEvaluationAssessment1List[].weightScore1',
      '!competency[].masfromEvaluationAssessment1List[].weightScore2',
      '!competency[].masfromEvaluationAssessment1List[].weightScore3',
      '!competency[].masfromEvaluationAssessment1List[].weightScore4',
      '!competency[].masfromEvaluationAssessment1List[].weightScore5',
      '!competency[].masfromEvaluationAssessment1List[].weightedTotal',
      '!competency[].masfromEvaluationAssessment1List[].averageScore',
      'pms',
      '!pms.gradeScore',
      '!pms.apsassessyDate',
      '!pms.apsapprove1Date',
      '!pms.apsapprove2Date',
      '!pms.apsapprove3Date',
      '!pms.apsapprove4Date',
      '!pms.apsapprove5Date',
      '!pms.netScore',
      '!pms.part1SumScore',
      '!pms.part2SumScore',
      '!pms.part3SumScore',
      '!pms.part4SumScore',
      '!pms.part5SumScore',
      '!pms.part6SumScore',
      '!pms.part7SumScore',
    ]
    const diffs = this.findDifferencesInclude(
      this.compentency.data,
      this.compentency.originalData,
      ignorePart
    );
    if (diffs.mini.length) {
      Swal.fire({
        icon: 'warning',
        title: 'มีการประเมินโดยที่ยังไม่มีการบันทึก',
        text: 'คุณต้องการเปลี่ยนรอบการประเมินหรือไม่',
        showCancelButton: true,
        confirmButtonText: 'ยืนยัน',
        cancelButtonText: 'ยกเลิก',
        customClass: {
          title: '!swal2-title-mt-20px',
          actions: '!swal2-actions-mt-20px',
          confirmButton: '!swal2-button-bg-green',
          cancelButton: '!swal2-button-bg-gray',
        },
      }).then((result) => {
        if (result.isConfirmed) {
          this.selectDataList(item)
        } else if (result.dismiss === Swal.DismissReason.cancel) {

        }
      })
    } else {
      this.selectDataList(item)
    }
  }

  deepClone(obj: any) {
    return JSON.parse(JSON.stringify(obj));
  }

  findDifferencesInclude(
    obj1: any,
    obj2: any,
    rawPaths: string[] = [''],
    prefix = ''
  ): { full: string[]; mini: string[] } {
    const full: string[] = [];
    const mini: string[] = [];

    const includePaths = rawPaths.filter(p => !p.startsWith('!'));
    const excludePaths = rawPaths
      .filter(p => p.startsWith('!'))
      .map(p => p.slice(1));

    // แปลง excludePaths เป็น regex สำหรับตรวจสอบ
    const excludePatterns = excludePaths.map(p => {
      const pattern = p.replace(/\./g, '\\.').replace(/\[\]/g, '\\[\\d+\\]');
      return new RegExp(`^${pattern}`);
    });

    const isExcluded = (path: string) => excludePatterns.some(r => r.test(path));
    const isIncluded = (path: string) => {
      if (includePaths.length === 0) return true;
      return includePaths.some(inc => path.startsWith(inc));
    };


    // ฟังก์ชันช่วยสร้าง path ใหม่
    const makePath = (base: string, key: string | number) =>
      base ? (typeof key === 'number' ? `${base}[${key}]` : `${base}.${key}`) : String(key);

    // เช็คกรณี array
    if (Array.isArray(obj1) && Array.isArray(obj2)) {
      const maxLength = Math.max(obj1.length, obj2.length);
      for (let i = 0; i < maxLength; i++) {
        const fullPath = makePath(prefix, i);
        if (isExcluded(fullPath) || !isIncluded(fullPath)) continue;

        const val1 = obj1[i];
        const val2 = obj2[i];
        if (val1 === val2) continue;

        if (val1 && val2 && typeof val1 === 'object' && typeof val2 === 'object') {
          const diffs = this.findDifferencesInclude(val1, val2, rawPaths, fullPath);
          full.push(...diffs.full);
          mini.push(...diffs.mini);
        } else {
          full.push(`${fullPath}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
          const cleanFieldName = String(i);
          mini.push(`${cleanFieldName}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
        }
      }
      return { full, mini };
    }

    // กรณี object
    const keys = new Set([
      ...(obj1 && typeof obj1 === 'object' ? Object.keys(obj1) : []),
      ...(obj2 && typeof obj2 === 'object' ? Object.keys(obj2) : []),
    ]);

    for (const key of keys) {
      const fullPath = makePath(prefix, key);
      if (isExcluded(fullPath) || !isIncluded(fullPath)) continue;

      const val1 = obj1?.[key];
      const val2 = obj2?.[key];
      if (val1 === val2) continue;

      const bothAreObjects = val1 && val2 && typeof val1 === 'object' && typeof val2 === 'object';

      if (bothAreObjects) {
        const diffs = this.findDifferencesInclude(val1, val2, rawPaths, fullPath);
        full.push(...diffs.full);
        mini.push(...diffs.mini);
      } else {
        full.push(`${fullPath}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
        const fieldName = String(key).replace(/\[\d+\]/g, '');
        mini.push(`${fieldName}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
      }
    }

    return { full, mini };
  }


  scrollToMenu(id: string) {
    setTimeout(() => {
      const container = this.scrollContainer?.nativeElement as HTMLElement;
      const target = document.getElementById(id);

      if (container && target) {
        const containerTop = container.getBoundingClientRect().top;
        const targetTop = target.getBoundingClientRect().top;
        const scrollOffset = targetTop - containerTop - 65;

        container.scrollTop += scrollOffset;
      }
    }, 0);
  }

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

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

}
