import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { LevelModel, MyLevelModel } from 'src/app/shared/model/level.model';
import { MyRoleModel, RoleModel } from 'src/app/shared/model/role.model';
import { MyUserModel, UserModel } from 'src/app/shared/model/user.model';
import { EmployeeService } from 'src/app/shared/services/employee.service';
import { FileService } from 'src/app/shared/services/file.service';
import { UserService } from 'src/app/shared/services/user.service';
export interface DataModal {
  search: string,
  currentPage: number,
  page: number[]
}
@Component({
  selector: 'app-user-settings',
  templateUrl: './user-settings.component.html',
  styleUrls: ['./user-settings.component.scss']
})
export class UserSettingsComponent {
  selectedFile: File | null = null;
  selectedFileName: string = 'กรุณาเลือกไฟล์';
  currentModal: 'add' | 'edit' | 'delete' = "add"
  search = ""
  modal: DataModal = {
    search: "",
    currentPage: 1,
    page: Array.from({ length: 1 }, (_, i) => i + 1)
  }

  companyId = ""
  user: { loading: boolean, select: UserModel, dataList: UserModel[] } = { loading: false, select: new MyUserModel(), dataList: [] }
  employee: { loading: boolean, select: EmployeeModel, dataList: { check: boolean, data: EmployeeModel }[] } = { loading: false, select: new MyEmployeeModel(), dataList: [] }
  role: { loading: boolean, select: RoleModel, dataList: { check: boolean, data: RoleModel }[] } = { loading: false, select: new MyRoleModel(), dataList: [] }
  level: { loading: boolean, select: LevelModel, dataList: { check: boolean, data: LevelModel }[] } = { loading: false, select: new MyLevelModel(), dataList: [] }

  columns: ColumnModel[] = [{
    field: "usernameId",
    headerText: "LoginName",
    type: "string",
    isPrimaryKey: true,
  },
  {
    field: "empId",
    headerText: "EmployeeCode",
    type: "string"
  },
  {
    field: "employee.fname",
    headerText: "FirstName",
    type: "string"
  },
  {
    field: "employee.lname",
    headerText: "LastName",
    type: "string"
  },
  {
    field: "status",
    headerText: "Status",
    type: "string"
  }]
  searchSettings = {
    fields: ['usernameId', 'empId', 'employee.fname', 'employee.lname', 'status'],
    operator: 'contains',
    ignoreCase: false
  }
  selectedItems: { key: string, count: number, data: Map<string, boolean> } = { key: '', count: 0, data: new Map<string, boolean>() };
  constructor(private toastr: ToastrService,
    private cdr: ChangeDetectorRef,
    private userService: UserService,
    private employeeService: EmployeeService,
    private fileService: FileService) {
    this.companyId = this.decodeJWT(sessionStorage.getItem("accessToken") || '').companyid
  }
  ngOnInit(): void {
    this.getUserList()
    this.getEmployeeList()
    this.getRoleList()
    this.getLevelList()
  }

  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);
  }
  getLevelList() {
    this.level.loading = true
    this.userService.getLevelList().subscribe({
      next: response => {
        this.level.dataList = response.map(x => ({ check: false, data: new MyLevelModel(x) }))
        this.level.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.level.loading = false
        this.cdr.detectChanges()
      }
    })
  }
  levelListFilter() {
    return this.level.dataList.filter(x => {
      const data = x.data
      const match = data.userLevel.toLowerCase().includes(this.modal.search.toLowerCase()) ||
        data.tdesc.toLowerCase().includes(this.modal.search.toLowerCase())
      return match
    })
  }
  selectLevel(data?: LevelModel) {
    this.user.select.level = new MyLevelModel(data)
  }

  getRoleList() {
    this.role.loading = true
    this.userService.getRoleList().subscribe({
      next: response => {
        this.role.dataList = response.map(x => ({ check: false, data: new MyRoleModel(x) }))
        this.role.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.role.loading = false
        this.cdr.detectChanges()
      }
    })
  }
  roleListFilter() {
    return this.role.dataList.filter(x => {
      const data = x.data
      const match = data.roleId.toLowerCase().includes(this.modal.search.toLowerCase()) ||
        data.tdesc.toLowerCase().includes(this.modal.search.toLowerCase())
      return match
    })
  }
  selectRole(data?: RoleModel) {
    this.user.select.role = new MyRoleModel(data)
  }

  getEmployeeList() {
    this.employee.loading = true
    this.employeeService.getList().subscribe({
      next: response => {
        this.employee.dataList = response.map(x => ({ check: false, data: new MyEmployeeModel(x) }))
        this.employee.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.employee.loading = false
        this.cdr.detectChanges()
      }
    })
  }
  employeeListFilter() {
    return this.employee.dataList.filter(x => {
      const data = x.data
      const match = data.employeeId.toLowerCase().includes(this.modal.search.toLowerCase()) ||
        data.thFullName.toLowerCase().includes(this.modal.search.toLowerCase())
      return match
    })
  }
  selectEmployee(data?: EmployeeModel) {
    this.user.select.employee = new MyEmployeeModel(data)
  }

  getUserList() {
    this.user.loading = true
    this.selectedItems.data.clear()
    this.userService.getList().subscribe({
      next: response => {
        this.user.dataList = response.map(x => {
          this.selectedItems.data.set(x.usernameId, false)
          return new MyUserModel({ ...x, status: x.status == '1' ? 'ใช้งาน' : 'ไม่ใช้งาน' })
        })
        this.selectedItems.key = 'usernameId'
        this.selectedItems.count = 0
        this.user.loading = false
        this.cdr.detectChanges()
      }, error: error => {
        this.user.loading = false
        this.cdr.detectChanges()
      }
    })
  }

  searchModalChange(dataList: any[]) {
    this.modal.currentPage = 1
    this.modal.page = Array.from({ length: Math.ceil(dataList.length / 10) }, (_, i) => i + 1);
    this.cdr.markForCheck()
  }

  selectUser(data?: UserModel) {
    if (data) {
      this.user.select = new MyUserModel({ ...data, companyId: data?.companyId || this.companyId, status: data.status == 'ใช้งาน' ? '1' : '0' })
    } else if (this.currentModal == 'add') {
      this.user.select = new MyUserModel({ companyId: this.companyId, status: '0' })
    } else if (this.currentModal == 'edit') {
      this.user.select = new MyUserModel({ usernameId: this.user.select.usernameId, companyId: this.companyId, status: '0' })
    }
  }
  onFileSelected(event: any) {
    this.selectedFile = event.target.files.length > 0 ? event.target.files[0] : null;
    this.selectedFileName = this.selectedFile?.name || "กรุณาเลือกไฟล์"
  }
  uploadFile() {
    if (!this.selectedFile) {
      alert('กรุณาเลือกไฟล์ก่อนอัปโหลด')
      return
    }
    const formData = new FormData();
    formData.append('file', this.selectedFile);
    this.user.loading = true
    this.fileService.uploadExcel(formData, 'muser').subscribe({
      next: response => {
        if (response.success) {
          this.showAlert(response.message, 'success')
          this.getUserList()
        } else {
          this.showAlert(response.message, 'error')
          this.user.loading = false
        }
      }, error: error => {
        this.showAlert(error.message, 'error')
        this.user.loading = false
      }
    })
  }
  downloadFile() {
    const fileName = 'IMPORT_USER.xlsx'
    this.fileService.downloadTemplate(fileName).subscribe({
      next: response => {
        const url = window.URL.createObjectURL(response);
        const a = document.createElement("a");
        a.href = url;
        a.download = fileName;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      }, error: error => {
        this.showAlert(error.message, 'error')
      }
    })

  }

  updateUser(typeApi: 'post' | 'delete') {
    if (this.currentModal == 'add') {
      this.user.loading = true
      this.userService.checkUser(this.user.select.usernameId).subscribe({
        next: response => {
          if (response.success) {
            this.updateUserApi(typeApi)
          } else {
            this.showAlert(response.message, 'error')
            this.user.loading = false
          }
          this.cdr.detectChanges()
        }, error: error => {
          this.showAlert(error.message, 'error')
          this.user.loading = false
          this.cdr.detectChanges()
        }
      })
    } else {
      this.updateUserApi(typeApi)
    }
  }
  updateUserApi(typeApi: 'post' | 'delete') {
    this.user.loading = true
    let body: UserModel | UserModel[]
    switch (this.currentModal) {
      case ('delete'): {
        const selectedKeys = Array.from(this.selectedItems.data.keys());
        body = this.user.dataList.filter(x => selectedKeys.includes(x.usernameId) && this.selectedItems.data.get(x.usernameId)).map(x => new MyUserModel({ ...x, status: x.status == 'ใช้งาน' ? '1' : '0' }))
        break;
      }
      default: {
        body = new MyUserModel(this.user.select)
      }
    }
    this.userService[typeApi]((body as any)).subscribe({
      next: response => {
        if (response.success) {
          this.showAlert(response.message, 'success')
          this.getUserList()
        } else {
          this.showAlert(response.message, 'error')
          this.user.loading = false
        }
        this.cdr.detectChanges()
      }, error: error => {
        this.showAlert(error.message, 'error')
        this.user.loading = false
        this.cdr.detectChanges()
      }
    })
  }

  selectDataModal(target: { [key: string]: any }, field: string, data: any) {
    target[field] = JSON.parse(JSON.stringify(data))
  }

  clearDataUser(currentModal: string) {
    if (currentModal == 'add') {
      this.selectUser()
    } else if (currentModal == 'edit') {
      this.selectEmployee()
      this.selectRole()
      this.selectLevel()
    }
  }
  showAlert(text: string, type: 'success' | 'error') {
    this.toastr[type](text, 'แจ้งเตือน', {
      timeOut: 3000,
      positionClass: 'toast-top-right',
    })
  }


  checkPrimary() {
    return this.user.dataList.find(x => x.usernameId == this.user.select.usernameId)
  }

  numSelectItem() {
    const selectedKeys = Array.from(this.selectedItems.data.keys());
    const num = this.user.dataList.filter(x => selectedKeys.includes(x.usernameId) && this.selectedItems.data.get(x.usernameId)).length
    return num
  }

  onSelectItemChange(arg: any) {
    this.selectedItems = arg
  }
}
