package com.xdap.self_development.service.impl;

import com.alibaba.excel.EasyExcel;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.api.moudle.department.pojo.entity.XdapDepartments;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.common.BusinessDatabase;
import com.xdap.self_development.common.MyResponse;
import com.xdap.self_development.controller.form.*;
import com.xdap.self_development.domain.pojo.ParameterPojo;
import com.xdap.self_development.domain.pojo.ResponsiblePersonPojo;
import com.xdap.self_development.domain.view.XdapUserView;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.listener.PersonReadListener;
import com.xdap.self_development.service.ResponsiblePersonService;
import com.xdap.self_development.service.XdapDeptUsersService;
import com.xdap.self_development.utils.DescriptionWriteUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 责任人服务实现类
 *
 * @version 1.0
 * @since 2025
 */
@Service
public class ResponsiblePersonServiceImpl implements ResponsiblePersonService {
    @Resource
    private BusinessDatabase bd;

    @Resource
    private XdapDeptUsersService xdapDeptUsersService;

    @Override
    /**
     * 保存责任人信息
     *
     * @param form 责任人表单数据
     */
    public void saveResponsiblePerson(ResponsiblePersonForm form) {
        List<ResponsiblePersonPojo> responsiblePeople = bd.getBusinessDatabase()
                .eq("department_id", form.getDepartmentId())
                .eq("subsystem", form.getSubsystem())
                .eq("personLevel", 1)
                .doQuery(ResponsiblePersonPojo.class);

        XdapDepartments currentDept = bd.getSystemDatabase()
                .eq("name", "研发总院")
                .doQueryFirst(XdapDepartments.class);
        if (currentDept == null) {
            throw new CommonException("没有找到研发总院");
        }
        XdapDepartments xdapDepartment = bd.getSystemDatabase()
                .eq("name", form.getDepartment())
                .eq("parent_id", currentDept.getId())
                .doQueryFirst(XdapDepartments.class);
        if (xdapDepartment == null) {
            throw new CommonException("在研发总院，找不到该部门");
        }


        if (!responsiblePeople.isEmpty()) {
            throw new CommonException("一个部门和子系统只能有一个责任人");
        }

        ResponsiblePersonPojo responsiblePerson = new ResponsiblePersonPojo();
        responsiblePerson.setDepartment(form.getDepartment());
        responsiblePerson.setDepartmentId(form.getDepartmentId());
        responsiblePerson.setUserId(form.getUserId());
        responsiblePerson.setSubsystem(form.getSubsystem());
        responsiblePerson.setPersonLevel(1);
        responsiblePerson.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
        bd.getBusinessDatabase().doInsert(responsiblePerson);
    }

    @Override
    /**
     * 保存填写人信息
     *
     * @param form 填写人表单数据
     */
    public void saveFilledPerson(FilledPersonForm form) {
        List<ResponsiblePersonPojo> responsiblePeople = bd.getBusinessDatabase()
                .eq("userId", form.getUserId())
                .eq("personLevel", 2)
                .doQuery(ResponsiblePersonPojo.class);

        if (!responsiblePeople.isEmpty()) {
            throw new CommonException("请不要重复新增填写人");
        }

        ResponsiblePersonPojo responsiblePerson = new ResponsiblePersonPojo();
        responsiblePerson.setDepartment(form.getDepartment());
        responsiblePerson.setDepartmentId(form.getDepartmentId());
        responsiblePerson.setUserId(form.getUserId());
        responsiblePerson.setSubsystem(form.getSubsystem());
        responsiblePerson.setPersonLevel(2);
        bd.getBusinessDatabase().doInsert(responsiblePerson);
    }

    @Override
    /**
     * 更新责任人信息
     *
     * @param form 更新责任人表单数据
     */
    public void updateResponsiblePerson(UpdateResponsiblePersonForm form) {
        bd.getBusinessDatabase()
                .rowid("id", form.getRowId())
                .update("department_id", form.getDepartmentId())
                .update("user_id", form.getUserId())
                .update("department", form.getDepartment())
                .update("subsystem", form.getSubsystem())
                .update("creation_date", Timestamp.valueOf(LocalDateTime.now()))
                .doUpdate(ResponsiblePersonPojo.class);
    }

    @Override
    /**
     * 更新填写人信息
     *
     * @param form 更新填写人表单数据
     */
    public void updateFilledPerson(UpdateFilledPersonForm form) {
        bd.getBusinessDatabase()
                .rowid("id", form.getRowId())
                .update("department_id", form.getDepartmentId())
                .update("user_id", form.getUserId())
                .update("department", form.getDepartment())
                .update("subsystem", form.getSubsystem())
                .update("parts_name", form.getPartsName())
                .doUpdate(ResponsiblePersonPojo.class);
    }

    @Override
    /**
     * 删除责任人信息
     *
     * @param rowId 行ID
     */
    public void deleteResponsiblePerson(String rowId) {
        bd.getBusinessDatabase()
                .rowid("id", rowId)
                .doDelete(ResponsiblePersonPojo.class);
    }

    @Override
    /**
     * 获取部门责任人信息
     *
     * @param form 部门责任人分页表单
     * @return 部门责任人分页查询结果
     */
    public PageQueryResult<ResponsiblePersonPojo> getDeptResponsible(DeptResponsiblePageForm form) {
        PageQueryResult<ResponsiblePersonPojo> result = bd.getBusinessDatabase()
                .viewQueryMode(true)
                .view("getResponsibleAndName")
                .setVar("level", 1)
                .doPageQuery(form.getPageNumber(), form.getPageSize(), ResponsiblePersonPojo.class);
        result.getResult().forEach(responsiblePersonPojo -> {
            XdapUsers user = bd.getSystemDatabase()
                    .eq("id", responsiblePersonPojo.getUserId())
                    .doQueryFirst(XdapUsers.class);
            if (user == null || user.getUsername() == null) {
                responsiblePersonPojo.setUsername("未知用户-" + responsiblePersonPojo.getUserId());
            } else {
                responsiblePersonPojo.setUsername(user.getUsername());
                responsiblePersonPojo.setUserAccount(user.getUserNumber());
            }
        });
        return result;
    }

    @Override
    /**
     * 获取部门填写人信息
     *
     * @param form 部门填写人分页表单
     * @return 部门填写人分页查询结果
     */
    public PageQueryResult<ResponsiblePersonPojo> getDeptFilled(DeptResponsiblePageForm form) {
        return bd.getBusinessDatabase()
                .viewQueryMode(true).view("getResponsibleAndName")
                .setVar("level", 2)
                .doPageQuery(form.getPageNumber(), form.getPageSize(), ResponsiblePersonPojo.class);
    }

    @Override
    /**
     * 判断用户是否为责任人
     *
     * @param userId 用户ID
     * @return 是否为责任人
     */
    public Boolean isResponsiblePerson(String userId) {
        List<ResponsiblePersonPojo> responsiblePeople = bd.getBusinessDatabase()
                .eq("userId", userId)
                .doQuery(ResponsiblePersonPojo.class);
        return !responsiblePeople.isEmpty();
    }

    @Override
    /**
     * 获取所有子系统
     *
     * @return 所有子系统的集合
     */
    public Set<String> getAllSubsystem() {
        List<ParameterPojo> templates = bd
                .getBusinessDatabase()
                .viewQueryMode(true)
                .view("getAllSubsystem")
                .doQuery(ParameterPojo.class);
        return templates.stream().map(ParameterPojo::getSubsystemName).collect(Collectors.toSet());
    }

    @Override
    /**
     * 根据部门和子系统获取用户
     *
     * @param dept 部门名称
     * @param subsystem 子系统名称
     * @return 部门用户的ArrayList
     */
    public ArrayList<XdapUsers> getUserBydepartment(String dept,String subsystem) {
        if (ObjectUtils.isEmpty(dept)) {
            return new ArrayList<>();
        }
        ArrayList<XdapUsers> xdapUsers1 = new ArrayList<>();
        List<ResponsiblePersonPojo> responsiblePeople = bd.getBusinessDatabase()
                .eq("department", dept)
                .eq("subsystem", subsystem)
                .doQuery(ResponsiblePersonPojo.class);
        if (!responsiblePeople.isEmpty()) {
            List<String> userIds = responsiblePeople.stream().map(ResponsiblePersonPojo::getUserId).collect(Collectors.toList());
            for (String userId : userIds) {
                XdapUsers xdapUsers = xdapDeptUsersService.selectUserByID(userId);
                if (xdapUsers != null) {
                    xdapUsers1.add(xdapUsers);
                }
            }
        }
        return xdapUsers1;
    }

    @Override
    /**
     * 导出责任人信息
     *
     * @param response HTTP响应对象
     */
    public void exportPerson(HttpServletResponse response) {
        String fileName = "部门责任人_" +
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        try {
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);

            List<ResponsiblePersonPojo> list = bd.getBusinessDatabase()
                    .viewQueryMode(true)
                    .view("getResponsibleAndName")
                    .setVar("level", 1)
                    .doQuery(ResponsiblePersonPojo.class);

            list.forEach(responsiblePersonPojo -> {
                XdapUsers user = bd.getSystemDatabase()
                        .eq("id", responsiblePersonPojo.getUserId())
                        .doQueryFirst(XdapUsers.class);
                if (user == null || user.getUsername() == null) {
                    responsiblePersonPojo.setUsername("未知用户-" + responsiblePersonPojo.getUserId());
                } else {
                    responsiblePersonPojo.setUsername(user.getUsername());
                    responsiblePersonPojo.setUserAccount(user.getUserNumber());
                }
            });

            EasyExcel.write(response.getOutputStream(), ResponsiblePersonPojo.class)
                    .registerWriteHandler(new DescriptionWriteUtils(ResponsiblePersonPojo.getFieldDescriptions()))
                    .includeColumnFieldNames(getIncludeColumnFieldNames())
                    .sheet("责任人")
                    .doWrite(list);
        } catch (Exception e) {
            throw new CommonException("导出Excel失败: " + e.getMessage());
        }
    }

    @Override
    /**
     * 导出空责任人模板
     *
     * @param response HTTP响应对象
     */
    public void exportVoidPerson(HttpServletResponse response) {
        String fileName = "部门责任人导入模板_" +
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        try {
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);

            List<ResponsiblePersonPojo> list = new ArrayList<>();
            list.add(new ResponsiblePersonPojo());

            EasyExcel.write(response.getOutputStream(), ResponsiblePersonPojo.class)
                    .registerWriteHandler(new DescriptionWriteUtils(ResponsiblePersonPojo.getFieldDescriptions()))
                    .includeColumnFieldNames(getIncludeColumnFieldNames())
                    .sheet("责任人")
                    .doWrite(list);
        } catch (Exception e) {
            throw new CommonException("导出Excel失败: " + e.getMessage());
        }
    }

    @Override
    /**
     * 导入责任人信息
     *
     * @param file 上传的文件
     * @param userId 用户ID
     * @return 操作响应结果
     */
    public MyResponse importPerson(MultipartFile file, String userId) {
        // 验证文件是否为工作表
        if (file == null || file.isEmpty()) {
            throw new CommonException("文件不能为空");
        }

        String filename = file.getOriginalFilename();
        if (filename == null ||
                !(filename.toLowerCase().endsWith(".xls") ||
                        filename.toLowerCase().endsWith(".xlsx"))) {
            throw new CommonException("只支持 .xls 或 .xlsx 格式的文件");
        }
        MyResponse problems =
                new MyResponse(false, new ArrayList<>(), new StringBuilder("已完成导入"));

        try (InputStream inputStream = file.getInputStream()) {
            EasyExcel.read(
                    inputStream,
                    ResponsiblePersonPojo.class,
                    new PersonReadListener(this, problems)
            ).doReadAll();

        } catch (IOException e) {
            throw new CommonException("读取文件失败");
        }

        return problems;
    }

    @Override
    /**
     * 根据部门和用户名获取用户视图
     *
     * @param department 部门名称
     * @param userAccount 用户账号
     * @param username 用户名
     * @return 用户视图对象
     */
    public XdapUserView getUserByDeptAndName(String department, String userAccount, String username) {
        XdapUserView xdapUserView = new XdapUserView();
        XdapDepartments xdapDepartments = bd.getSystemDatabase()
                .eq("name", "研发总院")
                .doQueryFirst(XdapDepartments.class);
        if (xdapDepartments == null) {
            return xdapUserView;
        }
        XdapDepartments currentDept = bd.getSystemDatabase()
                .eq("name", department)
                .eq("parent_id", xdapDepartments.getId())
                .doQueryFirst(XdapDepartments.class);

        if (currentDept != null) {
            xdapUserView.setDepartmentId(currentDept.getId());
        }
        if (userAccount != null) {
            XdapUsers currentUser = bd.getSystemDatabase()
                    .eq("user_number", userAccount)
                    .eq("username", username)
                    .eq("exit_status", "ENABLE")
                    .doQueryFirst(XdapUsers.class);
            if (currentUser != null) {
                xdapUserView.setUserId(currentUser.getId());
            }
        } else {
            List<XdapUsers> xdapUsers = bd.getSystemDatabase()
                    .eq("username", username)
                    .eq("exit_status", "ENABLE")
                    .doQuery(XdapUsers.class);
            if (xdapUsers.size() == 1) {
                xdapUserView.setUserId(xdapUsers.get(0).getId());
            }
        }
        return xdapUserView;
    }

    /**
     * 获取所有责任部门
     *
     * @return 责任部门列表
     */
    @Override
    public List<XdapDepartments> getResponsibleDepartment() {
        XdapDepartments currentDept = bd.getSystemDatabase()
                .eq("name", "研发总院")
                .doQueryFirst(XdapDepartments.class);
        if (currentDept == null) {
            return Collections.emptyList();
        }
        return bd.getSystemDatabase()
                .eq("parent_id", currentDept.getId())
                .doQuery(XdapDepartments.class);
    }

    @Override
    @Transactional
    /**
     * 导入所有责任人信息
     *
     * @param cachedDataList 缓存的数据列表
     * @param problems 问题收集对象
     */
    public void importAllPerson(List<ResponsiblePersonPojo> cachedDataList, MyResponse problems) {
        List<ResponsiblePersonPojo> list = new ArrayList<>();
        Map<String, List<ResponsiblePersonPojo>> departmentMap = new HashMap<>();
        cachedDataList.forEach(item -> {
            List<ResponsiblePersonPojo> responsiblePeople = bd.getBusinessDatabase()
                    .eq("department_id", item.getDepartmentId())
                    .eq("subsystem", item.getSubsystem())
                    .eq("person_level", 1)
                    .doQuery(ResponsiblePersonPojo.class);

            if (!responsiblePeople.isEmpty() || departmentMap.containsKey(item.getDepartment() + "-" + item.getSubsystem())) {
                problems.setFlag(true);
                problems.getErrors().add("部门:" + item.getDepartment() + "子系统:" + item.getSubsystem() + "已存在责任人");
            } else {
                departmentMap.put(item.getDepartment() + "-" + item.getSubsystem(), responsiblePeople);
                list.add(item);
            }
        });
        if (list.isEmpty() && !problems.isFlag()) {
            problems.setFlag(true);
            problems.getErrors().add("没有合适的责任人导入");
            return;
        }
        bd.getBusinessDatabase().doBatchInsert(list);
    }


    private List<String> getIncludeColumnFieldNames() {
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("department");
        fieldNames.add("subsystem");
        fieldNames.add("username");
        fieldNames.add("userAccount");
        return fieldNames;
    }
}
