package com.sundot.airport.attendance.portrait;

import cn.hutool.core.collection.CollectionUtil;
import com.sundot.airport.attendance.domain.AttendancePostRecord;
import com.sundot.airport.attendance.mapper.AttendancePostRecordMapper;
import com.sundot.airport.common.domain.portrait.BaseModuleIndicatorResult;
import com.sundot.airport.common.domain.portrait.IndicatorCalculateParams;
import com.sundot.airport.attendance.domain.portrait.WorkHoursStats;
import com.sundot.airport.common.enums.portrait.IndicatorType;
import com.sundot.airport.common.enums.portrait.UserType;
import com.sundot.airport.common.service.portrait.Indicator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 上岗时长
 * 个人：周期内上岗时数
 * 组织：周期内上岗总时数/平均人数
 */
@Component
public class WorkingHoursIndicator implements Indicator<Object> {

    @Autowired
    private AttendancePostRecordMapper attendancePostRecordMapper;

    private Object value;

    @Override
    public String getName() {
        return IndicatorType.WORKING_HOURS.getCode();
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void calculate(IndicatorCalculateParams params) {
        Long userId = params.getUserId();
        UserType userType = params.getUserType();
        if (UserType.PERSONAL.equals(userType)) {
            // 个人：周期内上岗时数（分钟）
            AttendancePostRecord record = new AttendancePostRecord();
            record.setUserId(userId);
            record.setCheckInTimeStart(params.getStartTime());
            record.setCheckInTimeEnd(params.getEndTime());
            List<AttendancePostRecord> records = attendancePostRecordMapper.selectAttendancePostRecordList(record);

            // 计算总工作时长
            long totalWorkingHours = records.stream()
                    .mapToLong(AttendancePostRecord::getWorkDuration)
                    .filter(workDuration -> workDuration > 0)
                    .sum();
            totalWorkingHours = totalWorkingHours > 0 ? totalWorkingHours / 60 : 0;
            this.value = totalWorkingHours;
        } else {
            // 组织：周期内上岗总时数/平均人数
            WorkHoursStats stats = new WorkHoursStats();

            // 部门id
            Long deptId = params.getDeptId();

            // 查询部门下所有用户的上岗记录
            AttendancePostRecord record = new AttendancePostRecord();
            switch (userType) {
                case TEAM:
                    record.setAttendanceTeamId(deptId);
                    break;
                case DEPARTMENT:
                    record.setAttendanceDepartmentId(deptId);
                    break;
                case BRIGADE:
                    record.setAttendanceBrigadeId(deptId);
                    break;
                case STATION:
                    record.setAttendanceStationId(deptId);
                    break;
                default:
                    break;
            }
            record.setCheckInTimeStart(params.getStartTime());
            record.setCheckInTimeEnd(params.getEndTime());
            List<AttendancePostRecord> records = attendancePostRecordMapper.selectAttendancePostRecordList(record);

            // 计算总工作时长
            long totalWorkingHours = records.stream()
                    .mapToLong(AttendancePostRecord::getWorkDuration)
                    .filter(workDuration -> workDuration > 0)
                    .sum();
            totalWorkingHours = totalWorkingHours > 0 ? totalWorkingHours / 60 : 0;

            stats.setTotalWorkingHours(totalWorkingHours);
            stats.setAveragePersonnel(CollectionUtil.isNotEmpty(params.getUserIds()) ? new BigDecimal(totalWorkingHours).divide(new BigDecimal(params.getUserIds().size()), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
            this.value = stats;
        }
    }

    @Override
    public void setResult(BaseModuleIndicatorResult result) {
        if (result instanceof AttendanceModuleIndicatorResult) {
            AttendanceModuleIndicatorResult attendanceResult = (AttendanceModuleIndicatorResult) result;
            attendanceResult.setWorkingHours(this.value);
        }
    }
}