package com.ruoyi.credit.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.credit.domain.ContractEmployeeLink;
import com.ruoyi.credit.domain.ServicePeriod;
import com.ruoyi.credit.domain.ServicePeriodEmployee;
import com.ruoyi.credit.domain.ServicePeriodLoan;
import com.ruoyi.credit.service.IContractEmployeeService;

/**
 * 合同员工关联Controller
 * 
 * @author ruoyi
 * @date 2025-12-23
 */
@RestController
@RequestMapping("/credit/contract-employee")
public class ContractEmployeeController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(ContractEmployeeController.class);

    @Autowired
    private IContractEmployeeService contractEmployeeService;

    // ==================== 合同员工关联管理 ====================

    /**
     * 关联单个员工到合同
     */
    @PreAuthorize("@ss.hasPermi('credit:contract:link')")
    @Log(title = "关联单个员工到合同", businessType = BusinessType.INSERT)
    @PostMapping("/link-employee")
    public AjaxResult linkIndividualEmployeeToContract(@RequestBody LinkEmployeeRequest request) {
        ContractEmployeeLink link = contractEmployeeService.linkIndividualEmployeeToContract(
                request.getContractId(), request.getEmployeeId(), request.getAssignedRole());
        return success(link);
    }

    /**
     * 批量关联员工到合同
     */
    @PreAuthorize("@ss.hasPermi('credit:contract:link')")
    @Log(title = "批量关联员工到合同", businessType = BusinessType.INSERT)
    @PostMapping("/link-multiple-employees")
    public AjaxResult linkMultipleEmployeesToContract(@RequestBody LinkMultipleEmployeesRequest request) {
        List<ContractEmployeeLink> links = contractEmployeeService.linkMultipleEmployeesToContract(
                request.getContractId(), request.getEmployeeIds(), request.getAssignedRole());
        return success(links);
    }

    /**
     * 查询合同关联的员工
     */
    @PreAuthorize("@ss.hasPermi('credit:contract:query')")
    @GetMapping("/contract/{contractId}/links")
    public AjaxResult getContractEmployeeLinks(@PathVariable("contractId") Long contractId) {
        List<ContractEmployeeLink> links = contractEmployeeService.getContractEmployeeLinks(contractId);
        return success(links);
    }

    /**
     * 取消合同员工关联
     */
    @PreAuthorize("@ss.hasPermi('credit:contract:unlink')")
    @Log(title = "取消合同员工关联", businessType = BusinessType.DELETE)
    @DeleteMapping("/unlink/{linkId}")
    public AjaxResult unlinkContractEmployee(@PathVariable("linkId") Long linkId) {
        return toAjax(contractEmployeeService.unlinkContractEmployee(linkId));
    }

    // ==================== 服务周期管理 ====================

    /**
     * 创建服务周期
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:add')")
    @Log(title = "创建服务周期", businessType = BusinessType.INSERT)
    @PostMapping("/service-periods")
    public AjaxResult createServicePeriod(@RequestBody ServicePeriod servicePeriod) {
        ServicePeriod created = contractEmployeeService.createServicePeriod(servicePeriod);
        return success(created);
    }

    /**
     * 查询服务周期详情
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods/{servicePeriodId}")
    public AjaxResult getServicePeriod(@PathVariable("servicePeriodId") Long servicePeriodId) {
        ServicePeriod servicePeriod = contractEmployeeService.getServicePeriod(servicePeriodId);
        return success(servicePeriod);
    }

    /**
     * 查询服务周期列表（分页）
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods")
    public TableDataInfo listServicePeriods(ServicePeriod servicePeriod) {
        startPage();
        List<ServicePeriod> list = contractEmployeeService.selectServicePeriodList(servicePeriod);
        return getDataTable(list);
    }

    /**
     * 查询合同的服务周期列表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/contracts/{contractId}/service-periods")
    public AjaxResult getServicePeriodsByContract(@PathVariable("contractId") Long contractId) {
        List<ServicePeriod> servicePeriods = contractEmployeeService.getServicePeriodsByContract(contractId);
        return success(servicePeriods);
    }

    /**
     * 更新服务周期
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:edit')")
    @Log(title = "更新服务周期", businessType = BusinessType.UPDATE)
    @PutMapping("/service-periods")
    public AjaxResult updateServicePeriod(@RequestBody ServicePeriod servicePeriod) {
        return toAjax(contractEmployeeService.updateServicePeriod(servicePeriod));
    }

    /**
     * 删除服务周期
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:remove')")
    @Log(title = "删除服务周期", businessType = BusinessType.DELETE)
    @DeleteMapping("/service-periods/{servicePeriodId}")
    public AjaxResult deleteServicePeriod(@PathVariable("servicePeriodId") Long servicePeriodId) {
        return toAjax(contractEmployeeService.deleteServicePeriod(servicePeriodId));
    }

    // ==================== 服务周期出勤员工选择 ====================

    /**
     * 为服务周期选择出勤员工
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:assign')")
    @Log(title = "选择出勤员工", businessType = BusinessType.INSERT)
    @PostMapping("/service-periods/{servicePeriodId}/select-attendance")
    public AjaxResult selectAttendanceEmployees(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody SelectAttendanceRequest request) {
        List<ServicePeriodEmployee> assignments = contractEmployeeService.selectAttendanceEmployees(
                servicePeriodId, request.getEmployeeIds(), request.getWorkDays());
        return success(assignments);
    }

    /**
     * 查询服务周期的员工分配
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods/{servicePeriodId}/employees")
    public AjaxResult getServicePeriodEmployees(@PathVariable("servicePeriodId") Long servicePeriodId) {
        List<com.ruoyi.credit.dto.ServicePeriodEmployeeDTO> employees = contractEmployeeService
                .getServicePeriodEmployeesWithInfo(servicePeriodId);
        return success(employees);
    }

    /**
     * 更新员工分配信息
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:edit')")
    @Log(title = "更新员工分配", businessType = BusinessType.UPDATE)
    @PutMapping("/service-period-employees")
    public AjaxResult updateServicePeriodEmployee(@RequestBody ServicePeriodEmployee servicePeriodEmployee) {
        return toAjax(contractEmployeeService.updateServicePeriodEmployee(servicePeriodEmployee));
    }

    /**
     * 移除服务周期员工分配
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:remove')")
    @Log(title = "移除员工分配", businessType = BusinessType.DELETE)
    @DeleteMapping("/service-period-employees/{assignmentId}")
    public AjaxResult removeServicePeriodEmployee(@PathVariable("assignmentId") Long assignmentId) {
        return toAjax(contractEmployeeService.removeServicePeriodEmployee(assignmentId));
    }

    /**
     * 批量移除服务周期员工分配
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:remove')")
    @Log(title = "批量移除员工分配", businessType = BusinessType.DELETE)
    @PostMapping("/service-periods/{servicePeriodId}/batch-remove-employees")
    public AjaxResult batchRemoveServicePeriodEmployees(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody BatchRemoveEmployeesRequest request) {
        Map<String, Object> result = contractEmployeeService.batchRemoveServicePeriodEmployees(
                servicePeriodId, request.getAssignmentIds());
        return success(result);
    }

    /**
     * 清空服务周期所有员工分配
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:remove')")
    @Log(title = "清空所有员工分配", businessType = BusinessType.DELETE)
    @DeleteMapping("/service-periods/{servicePeriodId}/clear-all-employees")
    public AjaxResult clearAllServicePeriodEmployees(@PathVariable("servicePeriodId") Long servicePeriodId) {
        Map<String, Object> result = contractEmployeeService.clearAllServicePeriodEmployees(servicePeriodId);
        return success(result);
    }

    // ==================== OCR信息提取 ====================

    /**
     * 通过OCR自动提取员工信息
     */
    @PreAuthorize("@ss.hasPermi('credit:contract:ocr')")
    @Log(title = "OCR提取员工信息", businessType = BusinessType.OTHER)
    @PostMapping("/ocr-extract")
    public AjaxResult extractEmployeeInfoFromOCR(@RequestParam("file") MultipartFile file) {
        Map<String, Object> result = contractEmployeeService.extractEmployeeInfoFromOCR(file);
        return success(result);
    }

    /**
     * 手动调整薪资标准
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:adjust')")
    @Log(title = "调整薪资标准", businessType = BusinessType.UPDATE)
    @PostMapping("/service-periods/{servicePeriodId}/adjust-salary")
    public AjaxResult adjustSalaryStandard(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody AdjustSalaryRequest request) {
        int result = contractEmployeeService.adjustSalaryStandard(
                servicePeriodId, request.getEmployeeId(), request.getAdjustedSalary(), request.getSalaryType());
        return toAjax(result);
    }

    /**
     * 批量调整薪资标准
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:adjust')")
    @Log(title = "批量调整薪资标准", businessType = BusinessType.UPDATE)
    @PostMapping("/service-periods/{servicePeriodId}/batch-adjust-salary")
    public AjaxResult batchAdjustSalaryStandards(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody BatchAdjustSalaryRequest request) {
        Map<String, Object> result = contractEmployeeService.batchAdjustSalaryStandards(
                servicePeriodId, request.getSalaryAdjustments());
        return success(result);
    }

    // ==================== 人工成本计算 ====================

    /**
     * 计算服务周期人工成本
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:calculate')")
    @GetMapping("/service-periods/{servicePeriodId}/calculate-cost")
    public AjaxResult calculateLaborCost(@PathVariable("servicePeriodId") Long servicePeriodId) {
        Map<String, Object> result = contractEmployeeService.calculateLaborCost(servicePeriodId);
        return success(result);
    }

    /**
     * 计算单个员工成本
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:calculate')")
    @GetMapping("/employees/{employeeId}/calculate-cost")
    public AjaxResult calculateEmployeeCost(@PathVariable("employeeId") Long employeeId,
            @RequestParam("workDays") Integer workDays,
            @RequestParam("salaryType") String salaryType) {
        BigDecimal cost = contractEmployeeService.calculateEmployeeCost(employeeId, workDays, salaryType);
        return success(cost);
    }

    /**
     * 重新计算服务周期总成本
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:calculate')")
    @Log(title = "重新计算总成本", businessType = BusinessType.UPDATE)
    @PostMapping("/service-periods/{servicePeriodId}/recalculate-cost")
    public AjaxResult recalculateTotalCost(@PathVariable("servicePeriodId") Long servicePeriodId) {
        BigDecimal totalCost = contractEmployeeService.recalculateTotalCost(servicePeriodId);
        return success(totalCost);
    }

    /**
     * 修复历史薪资计算错误的数据
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:fix')")
    @Log(title = "修复薪资计算数据", businessType = BusinessType.UPDATE)
    @PostMapping("/service-periods/{servicePeriodId}/fix-salary-calculation")
    public AjaxResult fixSalaryCalculationData(@PathVariable("servicePeriodId") Long servicePeriodId) {
        Map<String, Object> result = contractEmployeeService.fixSalaryCalculationData(servicePeriodId);
        return success(result);
    }

    /**
     * 测试贷款倍数计算
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:test')")
    @GetMapping("/service-periods/{servicePeriodId}/test-loan-calculation")
    public AjaxResult testLoanCalculation(@PathVariable("servicePeriodId") Long servicePeriodId) {
        log.info("测试贷款倍数计算: servicePeriodId={}", servicePeriodId);

        ServicePeriod servicePeriod = contractEmployeeService.getServicePeriod(servicePeriodId);
        if (servicePeriod == null) {
            return error("服务周期不存在");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("servicePeriodId", servicePeriodId);
        result.put("totalLaborCost", servicePeriod.getTotalLaborCost());
        result.put("loanMultiplier", servicePeriod.getLoanMultiplier());
        result.put("totalLoanAmount", servicePeriod.getTotalLoanAmount());

        // 手动计算预期的贷款金额
        BigDecimal expectedLoanAmount;
        if (servicePeriod.getLoanMultiplier() != null &&
                servicePeriod.getLoanMultiplier().compareTo(BigDecimal.ZERO) > 0 &&
                servicePeriod.getLoanMultiplier().compareTo(BigDecimal.ONE) != 0) {
            expectedLoanAmount = servicePeriod.getTotalLaborCost().multiply(servicePeriod.getLoanMultiplier());
        } else {
            expectedLoanAmount = servicePeriod.getTotalLaborCost();
        }
        result.put("expectedLoanAmount", expectedLoanAmount);
        result.put("calculationCorrect", expectedLoanAmount.equals(servicePeriod.getTotalLoanAmount()));

        return success(result);
    }

    // ==================== 数据验证 ====================

    /**
     * 验证员工是否可以分配到服务周期
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:validate')")
    @GetMapping("/validate-employee-assignment")
    public AjaxResult validateEmployeeAssignment(@RequestParam("employeeId") Long employeeId,
            @RequestParam("servicePeriodId") Long servicePeriodId) {
        Map<String, Object> result = contractEmployeeService.validateEmployeeAssignment(employeeId, servicePeriodId);
        return success(result);
    }

    /**
     * 测试部门ID设置功能
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:test')")
    @GetMapping("/test-department-id")
    public AjaxResult testDepartmentId() {
        try {
            Map<String, Object> result = new HashMap<>();
            
            // 1. 测试SecurityUtils获取部门ID
            Long securityDeptId = com.ruoyi.common.utils.SecurityUtils.getDeptId();
            result.put("securityDeptId", securityDeptId);
            log.info("SecurityUtils.getDeptId(): {}", securityDeptId);
            
            // 2. 测试DepartmentContextHolder获取部门ID
            Long contextDeptId = com.ruoyi.framework.security.context.DepartmentContextHolder.getCurrentDeptId();
            result.put("contextDeptId", contextDeptId);
            log.info("DepartmentContextHolder.getCurrentDeptId(): {}", contextDeptId);
            
            // 3. 测试超级管理员判断
            boolean isSuperAdmin = com.ruoyi.framework.security.context.DepartmentContextHolder.isSuperAdmin();
            result.put("isSuperAdmin", isSuperAdmin);
            log.info("DepartmentContextHolder.isSuperAdmin(): {}", isSuperAdmin);
            
            // 4. 测试创建ServicePeriod时的部门ID设置
            ServicePeriod testPeriod = new ServicePeriod();
            testPeriod.setContractId(1L); // 使用一个测试合同ID
            testPeriod.setServiceStartDate(new java.util.Date());
            testPeriod.setServiceEndDate(new java.util.Date());
            testPeriod.setServiceDays(30);
            
            result.put("testPeriodDeptIdBefore", testPeriod.getDeptId());
            log.info("创建ServicePeriod前: deptId = {}", testPeriod.getDeptId());
            
            // 调用部门权限验证器（不实际保存到数据库）
            try {
                com.ruoyi.framework.security.validator.DepartmentPermissionValidator validator = 
                    new com.ruoyi.framework.security.validator.DepartmentPermissionValidator();
                // 这里我们不能直接调用，因为需要依赖注入
                // 所以我们通过Service层来测试
                result.put("validatorTest", "需要通过Service层测试");
            } catch (Exception e) {
                result.put("validatorError", e.getMessage());
            }
            
            result.put("testPeriodDeptIdAfter", testPeriod.getDeptId());
            log.info("测试ServicePeriod后: deptId = {}", testPeriod.getDeptId());
            
            result.put("success", true);
            result.put("message", "部门ID测试完成");
            
            return success(result);
            
        } catch (Exception e) {
            log.error("部门ID测试异常", e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("message", "测试异常: " + e.getMessage());
            errorResult.put("error", e.getClass().getSimpleName());
            return error(errorResult.toString());
        }
    }

    // ==================== 服务周期贷款管理 ====================

    /**
     * 查询服务周期的贷款列表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods/{servicePeriodId}/loans")
    public AjaxResult getServicePeriodLoans(@PathVariable("servicePeriodId") Long servicePeriodId) {
        try {
            // 直接调用ServicePeriodLoanService获取贷款列表
            List<ServicePeriodLoan> loans = contractEmployeeService.getServicePeriodLoans(servicePeriodId);
            return success(loans);
        } catch (Exception e) {
            log.error("查询服务周期贷款列表失败: servicePeriodId={}", servicePeriodId, e);
            return error("查询贷款列表失败: " + e.getMessage());
        }
    }

    /**
     * 更新服务周期贷款信息
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:edit')")
    @Log(title = "更新服务周期贷款", businessType = BusinessType.UPDATE)
    @PutMapping("/service-period-loans/{loanId}")
    public AjaxResult updateServicePeriodLoan(@PathVariable("loanId") Long loanId,
            @RequestBody ServicePeriodLoan servicePeriodLoan) {
        try {
            servicePeriodLoan.setLinkId(loanId);
            return toAjax(contractEmployeeService.updateServicePeriodLoan(servicePeriodLoan));
        } catch (Exception e) {
            log.error("更新服务周期贷款失败: loanId={}", loanId, e);
            return error("更新贷款信息失败: " + e.getMessage());
        }
    }

    /**
     * 删除服务周期贷款信息
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:remove')")
    @Log(title = "删除服务周期贷款", businessType = BusinessType.DELETE)
    @DeleteMapping("/service-period-loans/{loanId}")
    public AjaxResult deleteServicePeriodLoan(@PathVariable("loanId") Long loanId) {
        try {
            return toAjax(contractEmployeeService.deleteServicePeriodLoanByLinkId(loanId));
        } catch (Exception e) {
            log.error("删除服务周期贷款失败: loanId={}", loanId, e);
            return error("删除贷款信息失败: " + e.getMessage());
        }
    }

    /**
     * 根据出勤记录申请贷款
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:loan')")
    @Log(title = "申请服务周期贷款", businessType = BusinessType.INSERT)
    @PostMapping("/service-periods/{servicePeriodId}/apply-loan")
    public AjaxResult applyLoanBasedOnAttendance(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody Map<String, Object> loanRequest) {
        Map<String, Object> result = contractEmployeeService.applyLoanBasedOnAttendance(servicePeriodId, loanRequest);
        return success(result);
    }

    /**
     * 验证贷款金额并获取允许范围
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @PostMapping("/service-periods/{servicePeriodId}/validate-loan-amount")
    public AjaxResult validateLoanAmountAndGetRange(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestBody Map<String, Object> request) {
        try {
            BigDecimal requestedAmount = new BigDecimal(request.get("requestedAmount").toString());
            Map<String, Object> result = contractEmployeeService.validateLoanAmountCalculation(servicePeriodId,
                    requestedAmount);
            return success(result);
        } catch (Exception e) {
            log.error("验证贷款金额失败: servicePeriodId={}", servicePeriodId, e);
            return error("验证贷款金额失败: " + e.getMessage());
        }
    }

    /**
     * 计算基于出勤数据的贷款金额
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods/{servicePeriodId}/calculate-loan-amount")
    public AjaxResult calculateLoanAmountBasedOnAttendance(@PathVariable("servicePeriodId") Long servicePeriodId) {
        Map<String, Object> result = contractEmployeeService.calculateLoanAmountBasedOnAttendance(servicePeriodId);
        return success(result);
    }

    /**
     * 根据合同期限选择银行融资条件
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:query')")
    @GetMapping("/service-periods/{servicePeriodId}/bank-financing")
    public AjaxResult selectBankFinancingByContractTerm(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestParam(required = false) Integer contractTermMonths) {
        Map<String, Object> result = contractEmployeeService.selectBankFinancingByContractTerm(servicePeriodId,
                contractTermMonths);
        return success(result);
    }

    /**
     * 生成服务周期贷款报表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:report')")
    @Log(title = "生成服务周期贷款报表", businessType = BusinessType.EXPORT)
    @PostMapping("/service-periods/{servicePeriodId}/loan-report")
    public AjaxResult generateServicePeriodLoanReport(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestParam(defaultValue = "COMPREHENSIVE") String reportType) {
        Map<String, Object> result = contractEmployeeService.generateServicePeriodLoanReport(servicePeriodId,
                reportType);
        return success(result);
    }

    /**
     * 导出服务周期贷款与出勤关联报表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period:export')")
    @Log(title = "导出贷款出勤关联报表", businessType = BusinessType.EXPORT)
    @GetMapping("/service-periods/{servicePeriodId}/export-loan-attendance")
    public AjaxResult exportLoanAttendanceReport(@PathVariable("servicePeriodId") Long servicePeriodId,
            @RequestParam(defaultValue = "EXCEL") String format) {
        Map<String, Object> result = contractEmployeeService.exportLoanAttendanceReport(servicePeriodId, format);
        return success(result);
    }
    // ==================== 请求对象定义 ====================

    public static class LinkEmployeeRequest {
        private Long contractId;
        private Long employeeId;
        private String assignedRole;

        // getters and setters
        public Long getContractId() {
            return contractId;
        }

        public void setContractId(Long contractId) {
            this.contractId = contractId;
        }

        public Long getEmployeeId() {
            return employeeId;
        }

        public void setEmployeeId(Long employeeId) {
            this.employeeId = employeeId;
        }

        public String getAssignedRole() {
            return assignedRole;
        }

        public void setAssignedRole(String assignedRole) {
            this.assignedRole = assignedRole;
        }
    }

    public static class LinkMultipleEmployeesRequest {
        private Long contractId;
        private List<Long> employeeIds;
        private String assignedRole;

        // getters and setters
        public Long getContractId() {
            return contractId;
        }

        public void setContractId(Long contractId) {
            this.contractId = contractId;
        }

        public List<Long> getEmployeeIds() {
            return employeeIds;
        }

        public void setEmployeeIds(List<Long> employeeIds) {
            this.employeeIds = employeeIds;
        }

        public String getAssignedRole() {
            return assignedRole;
        }

        public void setAssignedRole(String assignedRole) {
            this.assignedRole = assignedRole;
        }
    }

    public static class SelectAttendanceRequest {
        private List<Long> employeeIds;
        private Integer workDays;

        // getters and setters
        public List<Long> getEmployeeIds() {
            return employeeIds;
        }

        public void setEmployeeIds(List<Long> employeeIds) {
            this.employeeIds = employeeIds;
        }

        public Integer getWorkDays() {
            return workDays;
        }

        public void setWorkDays(Integer workDays) {
            this.workDays = workDays;
        }
    }

    public static class AdjustSalaryRequest {
        private Long employeeId;
        private BigDecimal adjustedSalary;
        private String salaryType;

        // getters and setters
        public Long getEmployeeId() {
            return employeeId;
        }

        public void setEmployeeId(Long employeeId) {
            this.employeeId = employeeId;
        }

        public BigDecimal getAdjustedSalary() {
            return adjustedSalary;
        }

        public void setAdjustedSalary(BigDecimal adjustedSalary) {
            this.adjustedSalary = adjustedSalary;
        }

        public String getSalaryType() {
            return salaryType;
        }

        public void setSalaryType(String salaryType) {
            this.salaryType = salaryType;
        }
    }

    public static class BatchAdjustSalaryRequest {
        private Map<Long, BigDecimal> salaryAdjustments;

        // getters and setters
        public Map<Long, BigDecimal> getSalaryAdjustments() {
            return salaryAdjustments;
        }

        public void setSalaryAdjustments(Map<Long, BigDecimal> salaryAdjustments) {
            this.salaryAdjustments = salaryAdjustments;
        }
    }

    public static class BatchRemoveEmployeesRequest {
        private List<Long> assignmentIds;

        // getters and setters
        public List<Long> getAssignmentIds() {
            return assignmentIds;
        }

        public void setAssignmentIds(List<Long> assignmentIds) {
            this.assignmentIds = assignmentIds;
        }
    }
}