package com.xdap.self_development.service.impl;

import com.definesys.mpaas.query.MpaasQuery;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.api.moudle.menus.pojo.XdapMenus;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.common.BusinessDatabase;
import com.xdap.self_development.common.YcTaskResult;
import com.xdap.self_development.controller.request.YcGetTodoTaskRequest;
import com.xdap.self_development.domain.dto.YcTodoTaskCommonResultDTO;
import com.xdap.self_development.domain.dto.YcTodoTaskResultDTO;
import com.xdap.self_development.domain.pojo.CompletedTaskPojo;
import com.xdap.self_development.domain.pojo.InitiatedTaskPojo;
import com.xdap.self_development.domain.pojo.TodoTaskPojo;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.service.XdapDeptUsersService;
import com.xdap.self_development.service.YcTaskResultService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class YcTaskResultServiceImpl implements YcTaskResultService {
    private static final Pattern POSITIVE_INTEGER_PATTERN = Pattern.compile("^[1-9]\\d*$");
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
    ;

    @Resource
    private BusinessDatabase bd;
    @Resource
    private XdapDeptUsersService xdapDeptUsersService;
    @Resource
    private com.xdap.runtime.service.RuntimeAppContextService runtimeAppContextService;
    @Value("${apaas.app.url}")
    private String frontUrl;
    @Value("${apaas.single.tenantId}")
    private String tenantId;
    @Value("${apaas.single.appId}")
    private String appId;

    public static String time2Str(Date creationDate) {
        if (creationDate == null) {
            return "";
        }
        return FORMATTER.format(creationDate.toInstant());
    }

    private String getTodoUrl() {
        XdapMenus xdapMenus = bd.getSystemDatabase()
                .eq("app_id", appId)
                .eq("menu_name", "我的待办")
                .doQueryFirst(XdapMenus.class);
        String menuId = xdapMenus == null ? "" : xdapMenus.getId();
        return frontUrl + "/" + tenantId + "/app/custom-page/apaas-custom-toDoList?appId=" + appId + "&menuType=CUSTOM&title=我的待办&url=apaas-custom-toDoList&currentMenu=" + menuId;
    }

    private String getCompletedUrl() {
        XdapMenus xdapMenus = bd.getSystemDatabase()
                .eq("app_id", appId)
                .eq("menu_name", "我发起的")
                .doQueryFirst(XdapMenus.class);
        String menuId = xdapMenus == null ? "" : xdapMenus.getId();
        return frontUrl + "/" + tenantId + "/app/custom-page/apaas-custom-myDone?appId=" + appId + "&menuType=CUSTOM&title=我发起的&url=apaas-custom-mySend&currentMenu=" + menuId;
    }

    private String getInitiatorUrl() {
        XdapMenus xdapMenus = bd.getSystemDatabase()
                .eq("app_id", appId)
                .eq("menu_name", "我的经办")
                .doQueryFirst(XdapMenus.class);
        String menuId = xdapMenus == null ? "" : xdapMenus.getId();
        return frontUrl + "/" + tenantId + "/app/custom-page/apaas-custom-mySend?appId=" + appId + "&menuType=CUSTOM&title=我的经办&url=apaas-custom-myDone&currentMenu=" + menuId;
    }

    /**
     * 返回云柴待办任务
     *
     * @param ycGetTodoTaskRequest 云柴获取待办任务请求对象
     * @return 云柴待办任务结果DTO列表
     */
    @Override
    public YcTaskResult returnTodoTask(YcGetTodoTaskRequest ycGetTodoTaskRequest) {
        YcTaskResult ycTaskResult = new YcTaskResult();
        String username = ycGetTodoTaskRequest.getUsername();
        if (ObjectUtils.isEmpty(username)) {
            ycTaskResult.setCode("error");
            return ycTaskResult;
        }
        ArrayList<YcTodoTaskResultDTO> dtos = new ArrayList<>();
        XdapUsers xdapUsers = xdapDeptUsersService.selectUserByCode(username);
        if (ObjectUtils.isNotEmpty(xdapUsers)) {
            String id = xdapUsers.getId();
            List<TodoTaskPojo> todoTaskPojos = bd.getBusinessDatabase()
                    .eq("owner_id", id)
                    .eq("is_delete", 0)
                    .orderBy("creation_date", "desc")
                    .doQuery(TodoTaskPojo.class);
            for (TodoTaskPojo todoTaskPojo : todoTaskPojos) {
                YcTodoTaskResultDTO dto = new YcTodoTaskResultDTO();
                dto.setTitle(todoTaskPojo.getProcessTitle());
                dto.setSystemName("研发数据管理平台");
                dto.setUpdateDate(time2Str(todoTaskPojo.getCreationDate()));
                dto.setActivityLabel(todoTaskPojo.getCurrentNode());
                dto.setUrl(getTodoUrl() + "&flowId=" + todoTaskPojo.getId());
                dtos.add(dto);
            }
            ycTaskResult.setCode("ok");
            ycTaskResult.setTable(dtos);
            ycTaskResult.setTotal((long) dtos.size());
            return ycTaskResult;
        }
        ycTaskResult.setCode("error");
        return ycTaskResult;
    }

    @Override
    public YcTaskResult returnCompleted(YcGetTodoTaskRequest ycGetTodoTaskRequest) {
        YcTaskResult ycTaskResult = new YcTaskResult();
        List<CompletedTaskPojo> completedTaskPojos = new ArrayList<>();
        if (ObjectUtils.isEmpty(ycGetTodoTaskRequest.getUsername())) {
            MpaasQuery query = bd.getBusinessDatabase()
                    .eq("is_delete", 0);
            queryData(ycGetTodoTaskRequest, query);
            List<CompletedTaskPojo> list = query
                    .doQuery(CompletedTaskPojo.class);
            completedTaskPojos.addAll(list);
        } else {
            XdapUsers user = bd.getSystemDatabase()
                    .eq("user_number", ycGetTodoTaskRequest.getUsername())
                    .doQueryFirst(XdapUsers.class);
            if (user == null) {
                throw new CommonException("用户不存在");
            }
            MpaasQuery query = bd.getBusinessDatabase()
                    .eq("owner_id", user.getId())
                    .eq("is_delete", 0);
            queryData(ycGetTodoTaskRequest, query);
            List<CompletedTaskPojo> result = query
                    .doQuery(CompletedTaskPojo.class);
            completedTaskPojos.addAll(result);
        }

        // 后处理
        List<CompletedTaskPojo> collect = new ArrayList<>(completedTaskPojos.stream()
                .collect(Collectors
                        .toMap(CompletedTaskPojo::getDocumentNo, Function.identity(),
                                BinaryOperator
                                        .maxBy(Comparator.comparing(CompletedTaskPojo::getCreationDate))))
                .values());
        Integer page = safeParsePageParam(ycGetTodoTaskRequest.getPage(), null);
        Integer pageSize = safeParsePageParam(ycGetTodoTaskRequest.getPageSize(), null);
        int fromIndex = page == null ? 0 : (page - 1) * pageSize;
        int toIndex = page == null ? collect.size() : Math.min(fromIndex + pageSize, collect.size());
        List<CompletedTaskPojo> paginatedList = collect.subList(fromIndex, toIndex);

        List<YcTodoTaskCommonResultDTO> list = new ArrayList<>();
        paginatedList.forEach(completedTaskPojo -> {
            YcTodoTaskCommonResultDTO dto = new YcTodoTaskCommonResultDTO();
            dto.setTitle(completedTaskPojo.getProcessTitle());
            dto.setCreateDate(time2Str(completedTaskPojo.getCreationDate()));
            dto.setActivityName(completedTaskPojo.getCurrentNode());
            dto.setSystemName("研发数据管理平台");
            dto.setUrl(getCompletedUrl() + "&flowId=" + completedTaskPojo.getId());
            list.add(dto);
        });
        ycTaskResult.setCode("ok");
        ycTaskResult.setTable(list);
        ycTaskResult.setTotal((long) collect.size());
        return ycTaskResult;
    }

    private Integer safeParsePageParam(String paramStr, Integer defaultValue) {
        if (paramStr == null || paramStr.trim().isEmpty()) {
            return defaultValue;
        }
        String cleanParam = paramStr.trim();

        if (!POSITIVE_INTEGER_PATTERN.matcher(cleanParam).matches()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(cleanParam);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    @Override
    public YcTaskResult returnInitiator(YcGetTodoTaskRequest ycGetTodoTaskRequest) {
        YcTaskResult ycTaskResult = new YcTaskResult();
        List<InitiatedTaskPojo> initiatedTaskPojos = new ArrayList<>();
        long total;
        if (ObjectUtils.isEmpty(ycGetTodoTaskRequest.getUsername())) {
            MpaasQuery query = bd.getBusinessDatabase()
                    .eq("is_delete", 0);
            queryData(ycGetTodoTaskRequest, query);
            List<InitiatedTaskPojo> list = query
                    .doQuery(InitiatedTaskPojo.class);
            initiatedTaskPojos.addAll(list);
            total = list.size();
        } else {
            XdapUsers user = bd.getSystemDatabase()
                    .eq("user_number", ycGetTodoTaskRequest.getUsername())
                    .doQueryFirst(XdapUsers.class);
            if (user == null) {
                throw new CommonException("用户不存在");
            }
            Integer page = safeParsePageParam(ycGetTodoTaskRequest.getPage(), 1);
            Integer pageSize = safeParsePageParam(ycGetTodoTaskRequest.getPageSize(), 10);
            MpaasQuery query = bd.getBusinessDatabase()
                    .eq("created_by_id", user.getId())
                    .eq("is_delete", 0);
            queryData(ycGetTodoTaskRequest, query);
            PageQueryResult<InitiatedTaskPojo> result = query
                    .doPageQuery(page, pageSize, InitiatedTaskPojo.class);
            total = result.getCount();
            initiatedTaskPojos.addAll(result.getResult());
        }

        List<YcTodoTaskCommonResultDTO> list = new ArrayList<>();
        initiatedTaskPojos.forEach(initiatedTaskPojo -> {
            YcTodoTaskCommonResultDTO dto = new YcTodoTaskCommonResultDTO();
            dto.setTitle(initiatedTaskPojo.getProcessTitle());
            dto.setCreateDate(time2Str(initiatedTaskPojo.getCreationDate()));
            dto.setActivityName(initiatedTaskPojo.getCurrentNode());
            dto.setUrl(getInitiatorUrl() + "&flowId=" + initiatedTaskPojo.getId());
            dto.setSystemName("研发数据管理平台");
            list.add(dto);
        });
        ycTaskResult.setCode("ok");
        ycTaskResult.setTable(list);
        ycTaskResult.setTotal(total);
        return ycTaskResult;
    }

    @Override
    public TodoTaskPojo getTodoById(String flowId) {
        TodoTaskPojo task = bd.getBusinessDatabase()
                .eq("id", flowId)
                .doQueryFirst(TodoTaskPojo.class);
        
        if (task == null) {
            throw new CommonException("任务不存在");
        }
        
        String currentUserId = runtimeAppContextService.getCurrentUserId();
        boolean isOwner = currentUserId.equals(task.getOwnerId());
        boolean isCreator = currentUserId.equals(task.getCreatedById());
        
        if (!isOwner && !isCreator) {
            throw new CommonException("无权限查看此任务");
        }
        
        return task;
    }

    @Override
    public InitiatedTaskPojo getInitiatorById(String flowId) {
        InitiatedTaskPojo task = bd.getBusinessDatabase()
                .eq("id", flowId)
                .doQueryFirst(InitiatedTaskPojo.class);
        
        if (task == null) {
            throw new CommonException("任务不存在");
        }
        
        String currentUserId = runtimeAppContextService.getCurrentUserId();
        boolean isCreator = currentUserId.equals(task.getCreatedById());
        
        if (!isCreator) {
            throw new CommonException("无权限查看此任务");
        }
        
        return task;
    }

    @Override
    public CompletedTaskPojo getCompletedById(String flowId) {
        CompletedTaskPojo task = bd.getBusinessDatabase()
                .eq("id", flowId)
                .doQueryFirst(CompletedTaskPojo.class);
        
        if (task == null) {
            throw new CommonException("任务不存在");
        }
        
        String currentUserId = runtimeAppContextService.getCurrentUserId();
        boolean isOwner = currentUserId.equals(task.getOwnerId());
        boolean isCreator = currentUserId.equals(task.getCreatedById());
        
        if (!isOwner && !isCreator) {
            throw new CommonException("无权限查看此任务");
        }
        
        return task;
    }

    private Date safeParseDateParam(String dateStr, Date defaultValue) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return defaultValue;
        }
        try {
            String trimmedDateStr = dateStr.trim();
            TemporalAccessor temporal = FORMATTER.parse(trimmedDateStr);
            Instant instant = Instant.from(temporal);
            return Date.from(instant);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    private void queryData(YcGetTodoTaskRequest ycGetTodoTaskRequest, MpaasQuery query) {
        if (ycGetTodoTaskRequest.getCreateDateStart() != null && !ycGetTodoTaskRequest.getCreateDateStart().isEmpty()) {
            Date createDateStart = safeParseDateParam(ycGetTodoTaskRequest.getCreateDateStart(), new Date());
            query.gteq("creation_date", createDateStart);
        }
        if (ycGetTodoTaskRequest.getCreateDateEnd() != null && !ycGetTodoTaskRequest.getCreateDateEnd().isEmpty()) {
            Date createDateEnd = safeParseDateParam(ycGetTodoTaskRequest.getCreateDateEnd(), new Date());
            query.lteq("creation_date", createDateEnd);
        }
    }
}
