package com.ecep.contract.ds.vendor.service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ecep.contract.IEntityService;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.QueryService;
import com.ecep.contract.constant.CompanyVendorConstant;
import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.ds.vendor.repository.VendorApprovedRepository;
import com.ecep.contract.model.VendorApproved;
import com.ecep.contract.model.VendorApprovedFile;
import com.ecep.contract.service.ServiceException;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.VendorApprovedVo;
import com.fasterxml.jackson.databind.JsonNode;

@Lazy
@Service
public class VendorApprovedService implements IEntityService<VendorApproved>, QueryService<VendorApprovedVo>,
        VoableService<VendorApproved, VendorApprovedVo> {
    private static final Logger logger = LoggerFactory.getLogger(VendorApprovedService.class);
    @Lazy
    @Autowired
    private VendorApprovedRepository repository;
    @Lazy
    @Autowired
    private VendorApprovedItemService itemService;
    @Lazy
    @Autowired
    private VendorApprovedFileService fileService;

    @Lazy
    @Autowired
    private SysConfService confService;

    public File getBasePath() {
        return new File(confService.getString(CompanyVendorConstant.KEY_APPROVED_LIST_BASE_PATH));
    }

    @Override
    public VendorApprovedVo findById(Integer id) {
        return repository.findById(id).map(VendorApproved::toVo).orElse(null);
    }

    @Override
    public VendorApproved getById(Integer id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public Page<VendorApproved> findAll(Specification<VendorApproved> spec, Pageable pageable) {
        return repository.findAll(spec, pageable);
    }

    @Override
    public Page<VendorApprovedVo> findAll(JsonNode paramsNode, Pageable pageable) {
        Specification<VendorApproved> spec = null;
        if (paramsNode.has("searchText")) {
            spec = getSpecification(paramsNode.get("searchText").asText());
        }
        // 添加额外的参数过滤
        spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "title");
        return findAll(spec, pageable).map(VendorApproved::toVo);
    }

    @Override
    public Specification<VendorApproved> getSpecification(String searchText) {
        if (!StringUtils.hasText(searchText)) {
            return null;
        }
        return (root, query, builder) -> {
            return builder.like(root.get("title"), "%" + searchText + "%");
        };
    }

    @Override
    public VendorApproved save(VendorApproved list) {
        return repository.save(list);
    }

    @Override
    public void delete(VendorApproved entity) {
        repository.delete(entity);
    }

    public Page<VendorApproved> findAll(Specification<VendorApproved> spec, PageRequest pageRequest) {
        return repository.findAll(spec, pageRequest);
    }

    public boolean makePathAbsent(VendorApproved list) {
        String path = list.getPath();
        if (StringUtils.hasText(path)) {
            File file = new File(path);
            if (file.exists()) {
                return false;
            }
        }

        File dir = makePath(list);
        if (dir == null) {
            return false;
        }
        if (!dir.exists()) {
            return false;
        }
        list.setPath(dir.getAbsolutePath());
        return true;
    }

    private File makePath(VendorApproved list) {
        File basePath = getBasePath();
        if (!basePath.exists()) {
            System.out.println("basePath = " + basePath);
            return null;
        }
        String title = list.getTitle();
        String fileName = FileUtils.escapeFileName(title);
        File dir = new File(basePath, fileName);
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                return null;
            }
        }
        return dir;
    }

    public boolean reBuildingFiles(VendorApproved list, Consumer<String> status) {
        String contractPath = list.getPath();
        if (!StringUtils.hasText(contractPath)) {
            return false;
        }
        List<VendorApprovedFile> dbFiles = fileService.findAllByList(list);
        List<VendorApprovedFile> retrieveFiles = new ArrayList<>();
        boolean modfied = false;

        Map<String, VendorApprovedFile> map = new HashMap<>();
        // 排除掉数据库中重复的
        for (VendorApprovedFile dbFile : dbFiles) {
            String fileName = dbFile.getFileName();
            // 没有文件信息，无效记录，删除
            if (!StringUtils.hasText(fileName)) {
                fileService.delete(dbFile);
                modfied = true;
                continue;
            }

            // 目录不存在，删除
            File dir = new File(contractPath, fileName);
            if (!dir.exists()) {
                fileService.delete(dbFile);
                modfied = true;
                continue;
            }

            VendorApprovedFile old = map.put(fileName, dbFile);
            // 目录有重复删除
            if (old != null) {
                fileService.delete(old);
                modfied = true;
            }
        }

        // 合同目录下的文件
        File dir = new File(list.getPath());
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 只处理文件
                    if (!file.isFile()) {
                        continue;
                    }
                    String fileName = file.getName();
                    if (!map.containsKey(fileName)) {
                        // 未记录
                        VendorApprovedFile filled = fillFileType(file, status);
                        retrieveFiles.add(filled);
                    }
                }
            }
        }
        status.accept("导入 " + retrieveFiles.size() + " 个文件");
        if (retrieveFiles.isEmpty()) {
            return modfied;
        }

        // update db
        retrieveFiles.forEach(v -> {
            v.setList(list);
            fileService.save(v);
        });
        return true;
    }

    public VendorApprovedFile fillFileType(File file, Consumer<String> status) {
        String fileName = file.getName();
        VendorApprovedFile vendorFile = new VendorApprovedFile();
        vendorFile.setFileName(file.getName());
        vendorFile.setSignDate(MyDateTimeUtils.pickLocalDate(fileName));

        return vendorFile;
    }

    @Override
    public void updateByVo(VendorApproved model, VendorApprovedVo vo) {
        if (model == null) {
            throw new ServiceException("VendorApproved cannot be null");
        }
        if (vo == null) {
            throw new ServiceException("VendorApprovedVo cannot be null");
        }

        // Map properties from VO to entity
        model.setTitle(vo.getTitle());
        model.setPublishDate(vo.getPublishDate());
        model.setPath(vo.getPath());
        model.setDescription(vo.getDescription());
    }

}
