package com.zioinfo.hrm.attendance;

import com.zioinfo.hrm.common.ApiResponse;
import com.zioinfo.hrm.common.AuthSupport;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/hrm/attendance")
@RequiredArgsConstructor
public class AttendanceController {

    private final AttendanceService attendanceService;

    @GetMapping
    public ApiResponse<Map<String, Object>> listAll(
            @RequestParam(required = false) String date,
            @RequestParam(required = false) Long deptId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "50") int size) {
        LocalDate d = date != null ? LocalDate.parse(date) : LocalDate.now();
        return ApiResponse.ok(attendanceService.listAll(d, deptId, page, size));
    }

    @GetMapping("/emp/{empId}")
    public ApiResponse<List<Map<String, Object>>> byEmp(
            @PathVariable Long empId,
            @RequestParam(defaultValue = "0") int year,
            @RequestParam(defaultValue = "0") int month) {
        int y = year == 0 ? LocalDate.now().getYear() : year;
        int m = month == 0 ? LocalDate.now().getMonthValue() : month;
        return ApiResponse.ok(attendanceService.getByEmpAndMonth(empId, y, m));
    }

    @PostMapping("/check-in/{empId}")
    public ApiResponse<Void> checkIn(@PathVariable Long empId, Authentication auth) {
        attendanceService.checkIn(empId, AuthSupport.actor(auth));
        return ApiResponse.ok(null);
    }

    @PostMapping("/check-out/{empId}")
    public ApiResponse<Void> checkOut(@PathVariable Long empId) {
        attendanceService.checkOut(empId);
        return ApiResponse.ok(null);
    }

    @GetMapping("/leaves/{empId}")
    public ApiResponse<List<Map<String, Object>>> getLeaves(
            @PathVariable Long empId,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "0") int year) {
        int y = year == 0 ? LocalDate.now().getYear() : year;
        return ApiResponse.ok(attendanceService.getLeaves(empId, status, y));
    }

    @PostMapping("/leaves/{empId}")
    public ApiResponse<Void> applyLeave(@PathVariable Long empId,
                                         @RequestBody Map<String, Object> leave, Authentication auth) {
        attendanceService.applyLeave(empId, leave, AuthSupport.actor(auth));
        return ApiResponse.ok(null);
    }

    @PatchMapping("/leaves/{id}/approve")
    public ApiResponse<Void> approveLeave(@PathVariable Long id,
                                           @RequestParam String status, Authentication auth) {
        AuthSupport.requireManager(auth);
        attendanceService.approveLeave(id, status, AuthSupport.actor(auth));
        return ApiResponse.ok(null);
    }

    @GetMapping("/leave-balance/{empId}")
    public ApiResponse<Map<String, Object>> leaveBalance(
            @PathVariable Long empId,
            @RequestParam(defaultValue = "0") int year) {
        int y = year == 0 ? LocalDate.now().getYear() : year;
        return ApiResponse.ok(attendanceService.getLeaveBalance(empId, y));
    }

    @GetMapping("/leave-types")
    public ApiResponse<List<Map<String, Object>>> leaveTypes() {
        return ApiResponse.ok(attendanceService.getLeaveTypes());
    }

    @GetMapping("/overtime/{empId}")
    public ApiResponse<List<Map<String, Object>>> overtime(
            @PathVariable Long empId,
            @RequestParam(defaultValue = "0") int year,
            @RequestParam(defaultValue = "0") int month) {
        int y = year == 0 ? LocalDate.now().getYear() : year;
        int m = month == 0 ? LocalDate.now().getMonthValue() : month;
        return ApiResponse.ok(attendanceService.getOvertime(empId, y, m));
    }

    @PostMapping("/overtime/{empId}")
    public ApiResponse<Void> addOvertime(@PathVariable Long empId,
                                          @RequestBody Map<String, Object> ot, Authentication auth) {
        attendanceService.addOvertime(empId, ot, AuthSupport.actor(auth));
        return ApiResponse.ok(null);
    }
}
