package com.ecep.contract.service;

import java.io.File;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.constant.CompanyConstant;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.vm.CompanyViewModel;
import com.ecep.contract.vo.CompanyVo;

import javafx.util.StringConverter;

@Service
@CacheConfig(cacheNames = "company")
public class CompanyService extends QueryService<CompanyVo, CompanyViewModel> {

    @Autowired
    private SysConfService confService;

    private File basePath;

    @Override
    public String getBeanName() {
        return "companyService";
    }

    public File getBasePath() {
        if (basePath == null) {
            basePath = new File(confService.getString(CompanyConstant.COMPANY_BASE_PATH));
        }
        return basePath;
    }

    @Cacheable(key = "#p0")
    public CompanyVo findById(Integer id) {
        return super.findById(id);
    }

    public CompanyVo findByName(String name) {
        List<CompanyVo> list = findAllByName(name);
        if (list.isEmpty()) {
            return null;
        }
        return list.getFirst();
    }

    public List<CompanyVo> findAllByName(String name) {
        Map<String, Object> params = new HashMap<>();
        params.put("name", name);
        return findAll(params, Pageable.unpaged()).getContent();
    }

    public void merge(CompanyVo company, CompanyVo updater) {
        // TODO Auto-generated method stub
        throw new UnsupportedOperationException("Unimplemented method 'merge'");
    }

    public CompanyVo createNewCompany(String newCompanyName) {
        CompanyVo company = new CompanyVo();
        company.setName(newCompanyName);
        company.setCreated(LocalDate.now());
        return company;
    }

    public boolean existsCompanyPath(CompanyVo company) {
        if (!StringUtils.hasText(company.getPath())) {
            return false;
        }

        File path = new File(company.getPath());
        return path.exists();
    }

    public boolean checkCompanyPathInBasePath(CompanyVo company) {
        if (!existsCompanyPath(company)) {
            return false;
        }
        File basePath = getBasePath();
        if (basePath == null || !basePath.exists()) {
            throw new IllegalArgumentException("basePath 不存在");
        }
        File path = new File(company.getPath());
        return path.getAbsolutePath().startsWith(basePath.getAbsolutePath());
    }

    public void verifyEnterpriseStatus(CompanyVo company, LocalDate verifyDate, MessageHolder holder) {
        // 检查营业状态
        String entStatus = company.getEntStatus();
        if (StringUtils.hasText(entStatus)) {
            if (entStatus.contains("注销")) {
                LocalDate end = company.getOperationPeriodEnd();
                LocalDate begin = company.getOperationPeriodBegin();
                if (begin == null || end == null) {
                    // 注销时间未知，无法判断是否在 verifyDate 之后注销
                    holder.error("营业状态异常：" + entStatus);
                } else {
                    if (!MyDateTimeUtils.dateValidFilter(verifyDate, begin, end, 0)) {
                        holder.error("营业状态异常：" + entStatus);
                    }
                }
            }
        } else {
            holder.error("营业状态异常：未设置");
        }
    }

    public boolean makePathAbsent(CompanyVo company, MessageHolder holder) {
        String path = company.getPath();
        if (StringUtils.hasText(path)) {
            File file = new File(path);
            if (file.exists()) {
                // holder.error("存储目录已存在，请检查：" + file.getAbsolutePath());
                return false;
            }
        }

        File dir = makePath(company, holder.sub("父级"));
        if (dir == null) {
            return false;
        }
        if (!dir.exists()) {
            holder.info("父级目录不存在：" + dir.getAbsolutePath());
            return false;
        }
        company.setPath(dir.getAbsolutePath());
        company.setPathExist(true);
        return true;
    }

    /**
     * 创建企业目录
     *
     * @param company 要创建的企业对象
     * @return 目录
     */
    public File makePath(CompanyVo company, MessageHolder holder) {
        File basePath = getBasePath();
        if (!basePath.exists()) {
            holder.error("存储目录不存在：" + basePath.getAbsolutePath());
            return null;
        }
        String companyName = company.getName();
        String district = company.getDistrict();
        if (!StringUtils.hasText(district)) {
            holder.error("区域异常：未设置");
            return null;
        }
        String parentPrefix = FileUtils.getParentPrefixByDistrict(district);
        if (parentPrefix == null) {
            holder.error("区域异常：" + district);
            return null;
        }
        File parent = new File(basePath, parentPrefix);
        if (!parent.exists()) {
            if (!parent.mkdir()) {
                holder.error("创建目录失败：" + parent.getAbsolutePath());
                return null;
            }
        }
        String fileName = FileUtils.escapeFileName(companyName);
        File dir = new File(parent, fileName);
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                holder.error("创建目录失败：" + dir.getAbsolutePath());
                return null;
            }
        }
        return dir;
    }

    @Override
    public StringConverter<CompanyVo> getStringConverter() {
        return super.getStringConverter();
    }
}
