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.constant.CompanyVendorConstant;
import com.ecep.contract.ds.company.CompanyFileUtils;
import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.ds.vendor.repository.CompanyVendorApprovedListRepository;
import com.ecep.contract.model.CompanyVendorApprovedFile;
import com.ecep.contract.model.CompanyVendorApprovedList;


@Lazy
@Service
public class CompanyVendorApprovedListService implements IEntityService<CompanyVendorApprovedList> {
    private static final Logger logger = LoggerFactory.getLogger(CompanyVendorApprovedListService.class);
    @Lazy
    @Autowired
    private CompanyVendorApprovedListRepository repository;
    @Lazy
    @Autowired
    private CompanyVendorApprovedItemService itemService;
    @Lazy
    @Autowired
    private CompanyVendorApprovedFileService fileService;

    @Lazy
    @Autowired
    private SysConfService confService;


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

    public CompanyVendorApprovedList findById(Integer id) {
        return repository.findById(id).orElse(null);
    }

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

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

    public CompanyVendorApprovedList save(CompanyVendorApprovedList list) {
        return repository.save(list);
    }

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

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

    public boolean makePathAbsent(CompanyVendorApprovedList 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(CompanyVendorApprovedList list) {
        File basePath = getBasePath();
        if (!basePath.exists()) {
            System.out.println("basePath = " + basePath);
            return null;
        }
        String title = list.getTitle();
        String fileName = CompanyFileUtils.escapeFileName(title);
        File dir = new File(basePath, fileName);
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                return null;
            }
        }
        return dir;
    }

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

        Map<String, CompanyVendorApprovedFile> map = new HashMap<>();
        // 排除掉数据库中重复的
        for (CompanyVendorApprovedFile 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;
            }

            CompanyVendorApprovedFile 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)) {
                        // 未记录
                        CompanyVendorApprovedFile 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 CompanyVendorApprovedFile fillFileType(File file, Consumer<String> status) {
        String fileName = file.getName();
        CompanyVendorApprovedFile vendorFile = new CompanyVendorApprovedFile();
        vendorFile.setFileName(file.getName());
        vendorFile.setSignDate(MyDateTimeUtils.pickLocalDate(fileName));

        return vendorFile;
    }

}
