package com.zioinfo.hrm.employee;

import com.zioinfo.hrm.common.CryptoUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class EmployeeService {

    private final EmployeeMapper employeeMapper;
    private final CryptoUtil cryptoUtil;

    public Map<String, Object> list(String keyword, Long deptId, String status, int page, int size) {
        int offset = (page - 1) * size;
        List<Employee> rows = employeeMapper.findAll(keyword, deptId, status, offset, size);
        // 전화번호 마스킹 처리
        rows.forEach(e -> e.setPhoneEnc(null));
        long total = employeeMapper.countAll(keyword, deptId, status);
        Map<String, Object> result = new HashMap<>();
        result.put("items", rows);
        result.put("total", total);
        result.put("page", page);
        result.put("size", size);
        return result;
    }

    public Employee getById(Long id) {
        Employee emp = employeeMapper.findById(id);
        if (emp != null) emp.setPhoneEnc(null); // PII 마스킹
        return emp;
    }

    @Transactional
    public Employee create(Employee emp, String actor) {
        // 사원번호 자동발번
        String lastNo = employeeMapper.getLastEmpNo();
        String newNo = generateEmpNo(lastNo);
        emp.setEmpNo(newNo);
        emp.setStatus("ACTIVE");
        emp.setCreatedBy(actor);
        if (emp.getPhoneEnc() != null && !emp.getPhoneEnc().isEmpty()) {
            emp.setPhoneEnc(cryptoUtil.encrypt(emp.getPhoneEnc()));
        }
        employeeMapper.insert(emp);
        return emp;
    }

    @Transactional
    public Employee update(Long id, Employee emp) {
        emp.setId(id);
        if (emp.getPhoneEnc() != null && !emp.getPhoneEnc().isEmpty()) {
            emp.setPhoneEnc(cryptoUtil.encrypt(emp.getPhoneEnc()));
        }
        employeeMapper.update(emp);
        return employeeMapper.findById(id);
    }

    @Transactional
    public void retire(Long id, LocalDate retireDate) {
        employeeMapper.updateStatus(id, "RETIRED", retireDate);
    }

    public List<Map<String, Object>> getCareer(Long empId) {
        return employeeMapper.getCareerList(empId);
    }

    @Transactional
    public void addCareer(Long empId, Map<String, Object> career) {
        career.put("empId", empId);
        employeeMapper.insertCareer(career);
    }

    public List<Map<String, Object>> getCerts(Long empId) {
        return employeeMapper.getCertList(empId);
    }

    @Transactional
    public void addCert(Long empId, Map<String, Object> cert) {
        cert.put("empId", empId);
        employeeMapper.insertCert(cert);
    }

    private String generateEmpNo(String last) {
        String year = DateTimeFormatter.ofPattern("yyyy").format(LocalDate.now());
        if (last == null || last.isEmpty()) {
            return "EMP-" + year + "-0001";
        }
        try {
            int seq = Integer.parseInt(last.substring(last.lastIndexOf('-') + 1)) + 1;
            return String.format("EMP-%s-%04d", year, seq);
        } catch (Exception e) {
            return "EMP-" + year + "-0001";
        }
    }
}
