import { Component, OnInit, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { InputTextModule } from 'primeng/inputtext';
import { SelectModule } from 'primeng/select';
import { TagModule } from 'primeng/tag';
import { ToastModule } from 'primeng/toast';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { DatePickerModule } from 'primeng/datepicker';
import { TextareaModule } from 'primeng/textarea';
import { MessageService, ConfirmationService } from 'primeng/api';
import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component';
import { HrAttendanceService } from '../../../core/services/hr-attendance.service';
import { HrEmployeeService } from '../../../core/services/hr-employee.service';
import { HrShiftService } from '../../../core/services/hr-shift.service';
import { HrAttendance } from '../../../core/models/hr-attendance.model';

@Component({
  selector: 'app-hr-attendance',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule,
    TranslateModule,
    TableModule,
    ButtonModule,
    DialogModule,
    InputTextModule,
    SelectModule,
    TagModule,
    ToastModule,
    ConfirmDialogModule,
    DatePickerModule,
    TextareaModule,
    PageHeaderComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './hr-attendance.component.html',
  styleUrl: './hr-attendance.component.scss',
})
export class HrAttendanceComponent implements OnInit {
  private fb = inject(FormBuilder);
  private messageService = inject(MessageService);
  private confirmationService = inject(ConfirmationService);
  private translate = inject(TranslateService);
  private attendanceService = inject(HrAttendanceService);
  private employeeService = inject(HrEmployeeService);
  private shiftService = inject(HrShiftService);

  dialogVisible = signal(false);
  editingItem = signal<HrAttendance | null>(null);
  tableLoading = signal(false);
  saving = signal(false);
  checkingIn = signal(false);
  checkingOut = signal(false);

  tableData = signal<HrAttendance[]>([]);
  totalRecords = signal(0);
  first = 0;
  rows = 25;

  employees: any[] = [];
  shifts: any[] = [];

  // Filters
  filterEmployeeId: number | null = null;
  filterDateFrom: Date | null = null;
  filterDateTo: Date | null = null;
  filterStatus: string | null = null;

  form!: FormGroup;

  statusOptions = [
    { label: 'Present', value: 'present' },
    { label: 'Absent', value: 'absent' },
    { label: 'Late', value: 'late' },
    { label: 'On Leave', value: 'on_leave' },
  ];

  ngOnInit(): void {
    this.initForm();
    this.loadPage();
    this.loadDependencies();
  }

  private initForm(): void {
    this.form = this.fb.group({
      employee_id: [null, Validators.required],
      date: [new Date(), Validators.required],
      check_in: [''],
      check_out: [''],
      shift_id: [null],
      notes: [''],
    });
  }

  private loadDependencies(): void {
    this.employeeService.listAll().subscribe({
      next: (res) => (this.employees = res.data),
    });
    this.shiftService.listAll().subscribe({
      next: (res) => (this.shifts = res.data),
    });
  }

  loadPage(page = 1, perPage = this.rows): void {
    this.tableLoading.set(true);
    const filters: Record<string, any> = {};
    if (this.filterEmployeeId) filters['employee_id'] = this.filterEmployeeId;
    if (this.filterDateFrom) filters['date_from'] = this.formatDate(this.filterDateFrom);
    if (this.filterDateTo) filters['date_to'] = this.formatDate(this.filterDateTo);
    if (this.filterStatus) filters['status'] = this.filterStatus;

    this.attendanceService.list(page, perPage, filters).subscribe({
      next: (res) => {
        this.tableData.set(res.data);
        this.totalRecords.set(res.meta.total);
        this.tableLoading.set(false);
      },
      error: () => this.tableLoading.set(false),
    });
  }

  onPageChange(event: any): void {
    this.first = event.first;
    this.rows = event.rows;
    const page = Math.floor(event.first / event.rows) + 1;
    this.loadPage(page, event.rows);
  }

  applyFilters(): void {
    this.first = 0;
    this.loadPage();
  }

  clearFilters(): void {
    this.filterEmployeeId = null;
    this.filterDateFrom = null;
    this.filterDateTo = null;
    this.filterStatus = null;
    this.first = 0;
    this.loadPage();
  }

  openNew(): void {
    this.editingItem.set(null);
    this.form.reset({ date: new Date() });
    this.dialogVisible.set(true);
  }

  editItem(item: HrAttendance): void {
    this.editingItem.set(item);
    this.form.patchValue({
      employee_id: item.employee_id,
      date: new Date(item.date),
      check_in: item.check_in || '',
      check_out: item.check_out || '',
      shift_id: item.shift_id,
      notes: item.notes || '',
    });
    this.dialogVisible.set(true);
  }

  onSave(): void {
    if (!this.form.valid) {
      this.form.markAllAsTouched();
      return;
    }

    const val = this.form.value;
    const data: any = {
      employee_id: val.employee_id,
      date: this.formatDate(val.date),
    };
    if (val.check_in) data.check_in = val.check_in;
    if (val.check_out) data.check_out = val.check_out;
    if (val.shift_id) data.shift_id = val.shift_id;
    if (val.notes) data.notes = val.notes;

    const isEdit = !!this.editingItem();
    const obs = isEdit
      ? this.attendanceService.update(this.editingItem()!.id, data)
      : this.attendanceService.create(data);

    this.saving.set(true);
    obs.subscribe({
      next: () => {
        this.saving.set(false);
        this.dialogVisible.set(false);
        this.reloadCurrentPage();
        this.messageService.add({
          severity: 'success',
          summary: this.translate.instant('COMMON.SUCCESS'),
          detail: isEdit
            ? this.translate.instant('COMMON.UPDATED')
            : this.translate.instant('COMMON.CREATED'),
        });
      },
      error: (err) => {
        this.saving.set(false);
        this.messageService.add({
          severity: 'error',
          summary: this.translate.instant('COMMON.ERROR'),
          detail: err.error?.message || 'Operation failed',
        });
      },
    });
  }

  deleteItem(item: HrAttendance): void {
    this.confirmationService.confirm({
      message: this.translate.instant('HR.ATTENDANCE.DELETE_CONFIRM'),
      header: this.translate.instant('COMMON.CONFIRM'),
      icon: 'pi pi-exclamation-triangle',
      acceptButtonStyleClass: 'p-button-danger',
      accept: () => {
        this.attendanceService.delete(item.id).subscribe({
          next: () => {
            this.reloadCurrentPage();
            this.messageService.add({
              severity: 'success',
              summary: this.translate.instant('COMMON.SUCCESS'),
              detail: this.translate.instant('COMMON.DELETED'),
            });
          },
          error: (err) => {
            this.messageService.add({
              severity: 'error',
              summary: this.translate.instant('COMMON.ERROR'),
              detail: err.error?.message || 'Delete failed',
            });
          },
        });
      },
    });
  }

  checkIn(): void {
    if (!this.filterEmployeeId) {
      this.messageService.add({
        severity: 'warn',
        summary: this.translate.instant('COMMON.WARNING'),
        detail: this.translate.instant('HR.ATTENDANCE.SELECT_EMPLOYEE_FIRST'),
      });
      return;
    }
    this.checkingIn.set(true);
    this.attendanceService.checkIn(this.filterEmployeeId).subscribe({
      next: () => {
        this.checkingIn.set(false);
        this.reloadCurrentPage();
        this.messageService.add({
          severity: 'success',
          summary: this.translate.instant('COMMON.SUCCESS'),
          detail: this.translate.instant('HR.ATTENDANCE.CHECK_IN_SUCCESS'),
        });
      },
      error: (err) => {
        this.checkingIn.set(false);
        this.messageService.add({
          severity: 'error',
          summary: this.translate.instant('COMMON.ERROR'),
          detail: err.error?.message || 'Check-in failed',
        });
      },
    });
  }

  checkOut(): void {
    if (!this.filterEmployeeId) {
      this.messageService.add({
        severity: 'warn',
        summary: this.translate.instant('COMMON.WARNING'),
        detail: this.translate.instant('HR.ATTENDANCE.SELECT_EMPLOYEE_FIRST'),
      });
      return;
    }
    this.checkingOut.set(true);
    this.attendanceService.checkOut(this.filterEmployeeId).subscribe({
      next: () => {
        this.checkingOut.set(false);
        this.reloadCurrentPage();
        this.messageService.add({
          severity: 'success',
          summary: this.translate.instant('COMMON.SUCCESS'),
          detail: this.translate.instant('HR.ATTENDANCE.CHECK_OUT_SUCCESS'),
        });
      },
      error: (err) => {
        this.checkingOut.set(false);
        this.messageService.add({
          severity: 'error',
          summary: this.translate.instant('COMMON.ERROR'),
          detail: err.error?.message || 'Check-out failed',
        });
      },
    });
  }

  getStatusSeverity(status: string): 'success' | 'info' | 'warn' | 'danger' | 'secondary' {
    switch (status) {
      case 'present':
        return 'success';
      case 'absent':
        return 'danger';
      case 'late':
        return 'warn';
      case 'on_leave':
        return 'info';
      default:
        return 'secondary';
    }
  }

  getEmployeeName(employeeId: number): string {
    const emp = this.employees.find((e) => e.id === employeeId);
    return emp ? emp.full_name : '-';
  }

  private reloadCurrentPage(): void {
    const currentPage = Math.floor(this.first / this.rows) + 1;
    this.loadPage(currentPage);
  }

  private formatDate(date: Date): string {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
  }
}
