package com.ecep.contract.service;

import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ecep.contract.SpringApp;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ProjectViewModel;
import com.ecep.contract.vo.ContractVo;
import com.ecep.contract.vo.DeliverySignMethodVo;
import com.ecep.contract.vo.ProductTypeVo;
import com.ecep.contract.vo.ProductUsageVo;
import com.ecep.contract.vo.ProjectIndustryVo;
import com.ecep.contract.vo.ProjectSaleTypeVo;
import com.ecep.contract.vo.ProjectTypeVo;
import com.ecep.contract.vo.ProjectVo;

@Service
public class ProjectService extends QueryService<ProjectVo, ProjectViewModel> {

    public ProjectVo findByName(String name) {
        Page<ProjectVo> page = findAll(ParamUtils.builder()
                .equals("name", name).build(),
                Pageable.ofSize(1));
        if (page.isEmpty()) {
            return null;
        }
        return page.getContent().getFirst();
    }

    public ProjectVo findByCode(String code) {
        Page<ProjectVo> page = findAll(ParamUtils.builder()
                .equals("code", code).build(),
                Pageable.ofSize(1));
        if (page.isEmpty()) {
            return null;
        }
        return page.getContent().getFirst();
    }

    public void applyCode(ProjectVo project, String code) {
        project.setCode(code);

        String saleTypeCode = null;
        String seqCode = null;
        String extCode = null;
        // 第二个字符是数字时,快速处理
        if (Character.isDigit(code.charAt(1))) {
            // 只有一个字母表示合同类型
            saleTypeCode = String.valueOf(code.charAt(0));
            seqCode = code.substring(1, 6);
            extCode = code.substring(6);
        } else {
            // 使用正则找出 A-Z 1~4字母引导 合同类型
            String regex = "^([A-Z]{1,4})(\\d{4,5})([A-Z]{0,5})";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(code);
            if (matcher.find()) {
                saleTypeCode = matcher.group(1);
                seqCode = matcher.group(2);
                extCode = matcher.group(3);
            }
        }

        ProjectSaleTypeVo saleType = SpringApp.getBean(ProjectSaleTypeService.class).findByCode(saleTypeCode);
        if (saleType != null) {
            project.setSaleTypeId(saleType.getId());
        }

        if (seqCode != null) {
            project.setCodeYear(Integer.parseInt(seqCode.substring(0, 2)));
            project.setCodeSequenceNumber(Integer.parseInt(seqCode.substring(2)));
        }

        if (extCode != null) {
            // 4个后缀编码
            if (extCode.length() > 3) {
                DeliverySignMethodVo signMethod = SpringApp.getBean(DeliverySignMethodService.class)
                        .findBySaleTypeAndCode(saleType,
                                String.valueOf(extCode.charAt(0)));
                if (signMethod != null) {
                    project.setDeliverySignMethodId(signMethod.getId());
                }

                ProductTypeVo productType = SpringApp.getBean(ProductTypeService.class)
                        .findByCode(extCode.substring(1, 2));
                if (productType != null) {
                    project.setProductTypeId(productType.getId());
                }
                ProjectTypeVo projectType = SpringApp.getBean(ProjectTypeService.class)
                        .findByCode(extCode.substring(2, 3));
                if (projectType != null) {
                    project.setProjectTypeId(projectType.getId());
                }

                ProjectIndustryVo industry = SpringApp.getBean(ProjectIndustryService.class)
                        .findByCode(extCode.substring(3, 4));
                if (industry != null) {
                    project.setIndustryId(industry.getId());
                }
            }
            // 扩展至 5个后缀编码
            if (extCode.length() > 4) {
                ProductUsageVo productUsage = SpringApp.getBean(ProductUsageService.class)
                        .findByCode(extCode.substring(4, 5));
                if (productUsage != null) {
                    project.setProductUsageId(productUsage.getId());
                }
            }
        }
    }

    public ProjectVo newInstanceByContract(ContractVo contract) {
        ProjectVo project = new ProjectVo();
        project.setName(contract.getName());
        applyCode(project, contract.getCode());
        contract.setCreated(LocalDateTime.now());
        LocalDateTime created = contract.getCreated();
        if (created != null) {
            project.setCreated(created.toLocalDate());
        } else {
            project.setCreated(LocalDate.now());
        }
        project.setCustomerId(contract.getCompanyId());
        project.setApplicantId(contract.getEmployeeId());
        return project;
    }

    public File searchPath(ProjectVo project) {
        Integer saleTypeId = project.getSaleTypeId();
        if (saleTypeId == null) {
            return null;
        }
        ProjectSaleTypeVo saleType = SpringApp.getBean(ProjectSaleTypeService.class).findById(saleTypeId);
        if (saleType == null) {
            return null;
        }
        if (!StringUtils.hasText(saleType.getPath())) {
            return null;
        }
        File path = new File(saleType.getPath());
        if (saleType.isStoreByYear()) {
            path = new File(path, "20" + project.getCodeYear());
            if (!path.exists()) {
                path.mkdir();// 创建目录
            }
        }

        String projectCode = makeProjectCode(project);
        // 检索目录
        File[] files = path.listFiles(f -> f.isDirectory() && f.getName().contains(projectCode));
        if (files != null && files.length > 0) {
            path = files[0];
        }
        return path;
    }

    public String makeProjectCode(ProjectVo project) {
        StringBuilder sb = new StringBuilder();
        Integer saleTypeId = project.getSaleTypeId();
        if (saleTypeId != null) {
            ProjectSaleTypeVo saleType = SpringApp.getBean(ProjectSaleTypeService.class).findById(saleTypeId);
            if (saleType != null) {
                sb.append(saleType.getCode());
            }
        }
        sb.append(project.getCodeYear());
        if (project.getCodeSequenceNumber() < 10) {
            sb.append("0");
        }
        if (project.getCodeSequenceNumber() < 100) {
            sb.append("0");
        }
        sb.append(project.getCodeSequenceNumber());
        return sb.toString();
    }

    public int getNextCodeSequenceNumber(ProjectSaleTypeVo type, int year) {
        PageRequest pageable = PageRequest.of(0, 1, Sort.by(Direction.DESC, "codeSequenceNumber"));
        Page<ProjectVo> page = findAll(ParamUtils.builder()
                .equals("type", type.getId())
                .equals("codeYear", year).build(),
                pageable);
        if (page.isEmpty()) {
            return 1;
        }
        return page.getContent().getFirst().getCodeSequenceNumber() + 1;
    }

    public ProjectVo findBySaleTypeAndCodeYearAndCodeSequenceNumber(int typeId, int codeYear,
            int codeSequenceNumber) {
        Page<ProjectVo> page = findAll(ParamUtils.builder()
                .equals("type", typeId)
                .equals("codeYear", codeYear)
                .equals("codeSequenceNumber", codeSequenceNumber).build(),
                Pageable.ofSize(1));
        if (page.isEmpty()) {
            return null;
        }
        return page.getContent().getFirst();
    }
}
