package com.ecep.contract.cloud.u8.ctx;

import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.cloud.old.OldVersionService;
import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEntity;
import com.ecep.contract.model.CustomerCatalog;

import lombok.Setter;

public class CustomerCtx extends AbstractYongYouU8Ctx {
    private static final String AUTO_CREATE_CUSTOMER_AFTER = "cloud.u8.auto-create-customer-after";
    @Setter
    private CompanyCtx companyCtx;
    @Setter
    private ContractCtx contractCtx;
    @Setter
    private CompanyBankAccountCtx companyBankAccountCtx;
    @Setter
    private CompanyCustomerEntityService customerEntityService;

    public CompanyCtx getCompanyCtx() {
        if (companyCtx == null) {
            companyCtx = new CompanyCtx();
            companyCtx.from(this);
        }
        return companyCtx;
    }

    ContractCtx getContractCtx() {
        if (contractCtx == null) {
            contractCtx = new ContractCtx();
            contractCtx.from(this);
        }
        return contractCtx;
    }

    CompanyBankAccountCtx getCompanyBankAccountCtx() {
        if (companyBankAccountCtx == null) {
            companyBankAccountCtx = new CompanyBankAccountCtx();
            companyBankAccountCtx.from(this);
        }
        return companyBankAccountCtx;
    }

    CompanyCustomerEntityService getCustomerEntityService() {
        if (customerEntityService == null) {
            customerEntityService = SpringApp.getBean(CompanyCustomerEntityService.class);
        }
        return customerEntityService;
    }

    /**
     * 更新客户相关项
     *
     * @param item
     * @param unitCode
     * @param holder
     */
    public CompanyCustomerEntity updateCustomerEntityDetailByCode(CompanyCustomerEntity item, String unitCode, MessageHolder holder) {
        if (applyEntityDetail(item, repository.findCustomerByCusCode(unitCode), holder)) {
            item = save(item);
        }
        return item;
    }

    public boolean applyEntityDetail(CompanyCustomerEntity item, Map<String, Object> map, MessageHolder holder) {

        String name = (String) map.get("cCusName");
        String abbName = (String) map.get("cCusAbbName");
        String cusCode = (String) map.get("cCusCode");
        String classCode = (String) map.get("cCCCode");

        String createPerson = (String) map.get("cCreatePerson");
        String modifyPerson = (String) map.get("cModifyPerson");
        java.sql.Date devDate = (java.sql.Date) map.get("devDate");
        java.sql.Timestamp modifyDate = (java.sql.Timestamp) map.get("dModifyDate");

        String bank = (String) map.get("cCusBank");
        String bankAccount = (String) map.get("cCusAccount");


        boolean modified = false;
        if (updateText(item::getName, item::setName, name, holder, "名称")) {
            modified = true;
        }
        if (updateText(item::getAbbName, item::setAbbName, abbName, holder, "简称")) {
            modified = true;
        }
        if (updateText(item::getCode, item::setCode, cusCode, holder, "客户编号")) {
            modified = true;
        }

        if (updateCustomerCatalog(item::getCatalog, item::setCatalog, classCode, holder, "分类")) {
            modified = true;
        }
        if (updateEmployeeByName(item::getCreator, item::setCreator, createPerson, holder, "创建人")) {
            modified = true;
        }
        if (updateEmployeeByName(item::getModifier, item::setModifier, modifyPerson, holder, "修改人")) {
            modified = true;
        }
        if (updateLocalDate(item::getDevelopDate, item::setDevelopDate, devDate, holder, "发展日期")) {
            modified = true;
        }
        if (updateLocalDate(item::getModifyDate, item::setModifyDate, modifyDate, holder, "修改日期")) {
            modified = true;
        }

        if (modified) {
            LocalDate today = LocalDate.now();
            if (item.getUpdatedDate() == null || item.getUpdatedDate().isBefore(today)) {
                item.setUpdatedDate(today);
                holder.info("更新日期更新为 " + today);
            }
        }

        CompanyCustomer customer = item.getCustomer();
        if (customer == null) {
            // 如果没有关联客户，则根据供应商名称或别名查找公司
            Company company = findOrCreateCompanyByCustomerEntity(item, holder);
            if (company != null) {
                // 找到客户

                customer = getCompanyCustomerService().findByCompany(company);
                if (customer == null) {
                    customer = createCustomerByCustomerEntity(item, holder);
                    if (customer != null) {
                        customer.setCompany(company);
                        customer = getCompanyCustomerService().save(customer);
                    }
                }

                if (customer != null) {
                    item.setCustomer(customer);
                    modified = true;
                }
            }

        }
        if (customer != null) {
            if (!Hibernate.isInitialized(customer)) {
                customer = getCompanyCustomerService().findById(customer.getId());
            }
            Company company = customer.getCompany();
            if (company != null) {
                getCompanyBankAccountCtx().updateBankAccount(company, bank, bankAccount, holder);
            }
        }
        return modified;
    }

    private boolean updateCustomerCatalog(Supplier<CustomerCatalog> getter, Consumer<CustomerCatalog> setter, String catalogCode, MessageHolder holder, String topic) {
        CustomerCatalog catalog = null;
        if (StringUtils.hasText(catalogCode)) {
            catalog = getCompanyCustomerService().findCatalogByCode(catalogCode);
        }
        if (catalog == null) {
            setter.accept(null);
            holder.warn("无效" + topic + "：" + catalogCode);
            return true;
        } else {
            if (!Objects.equals(getter.get(), catalog)) {
                if (!Hibernate.isInitialized(catalog)) {
                    catalog = getCompanyCustomerService().findCatalogByCode(catalogCode);
                }
                setter.accept(catalog);
                holder.info(topic + "修改为: " + catalog.getName());
                return true;
            }
        }
        return false;
    }

    public boolean syncCustomer(Company company, MessageHolder holder) {
        CompanyCustomer companyCustomer = getCompanyCustomerService().findByCompany(company);
        if (companyCustomer == null) {
            holder.error("客户未创建, 如需要请手动创建.");
            return false;
        }
        // 检索相关项
        List<CompanyCustomerEntity> entities = getCustomerEntityService().findAllByCustomer(companyCustomer);
        if (entities.isEmpty()) {
            holder.error("客户未关联任何相关项");
            return false;
        }

        boolean updated = false;
        boolean companyModified = false;

        // 更新相关项
        for (CompanyCustomerEntity entity : entities) {
            if (!StringUtils.hasText(entity.getCode())) {
                holder.warn("相关项：" + entity.getCode() + " 无效，跳过");
                continue;
            }
            if (applyEntityDetail(entity, repository.findCustomerByCusCode(entity.getCode()), holder)) {
                entity = getCustomerEntityService().save(entity);
            }

            if (getCompanyCtx().updateCompanyNameIfAbsent(company, entity.getName(), holder)) {
                companyModified = true;
            }
            if (getCompanyCtx().updateCompanyAbbNameIfAbsent(company, entity.getAbbName(), holder)) {
                companyModified = true;
            }
        }

        if (companyModified) {
            company = getCompanyService().save(company);
            updated = true;
        }

        // 更新客户的开发日期
        if (updateCustomerDevelopDate(companyCustomer, entities, holder)) {
            companyCustomer = getCompanyCustomerService().save(companyCustomer);
            updated = true;
        }

        for (CompanyCustomerEntity entity : entities) {
            if (getContractCtx().syncByCustomerEntity(companyCustomer, entity, holder)) {
                updated = true;
            }
        }
        return updated;
    }

    private boolean updateCustomerDevelopDate(CompanyCustomer companyCustomer, List<CompanyCustomerEntity> entities, MessageHolder holder) {
        LocalDate developDate = null;
        for (CompanyCustomerEntity entity : entities) {
            // 取最早的开发日期
            if (developDate == null || entity.getDevelopDate().isBefore(developDate)) {
                developDate = entity.getDevelopDate();
            }
        }
        return updateLocalDate(companyCustomer::getDevelopDate, companyCustomer::setDevelopDate, developDate, holder, "开发日期");
    }

    public CompanyCustomerEntity findOrCreateByCode(Map<String, Object> rs, String cusCode, MessageHolder subHolder) {
        CompanyCustomerEntityService customerEntityService = getCompanyCustomerEntityService();
        CompanyCustomerEntity entity = customerEntityService.findByCustomerCode(cusCode);
        if (entity == null) {
            entity = new CompanyCustomerEntity();
            entity.setCode(cusCode);
            entity = customerEntityService.save(entity);
            subHolder.info("创建客户相关项：" + cusCode);
        }
        return entity;
    }

    private CompanyCustomer createCustomerByCustomerEntity(CompanyCustomerEntity entity, MessageHolder holder) {
        LocalDate developDate = entity.getDevelopDate();
        if (developDate == null) {
            holder.warn(entity.getName() + " 没有设置开发日期，跳过");
            return null;
        }
        // 创建发展日期从2023年1月1日后的
        LocalDate start = LocalDate.of(2023, 1, 1);
        String autoCreateAfter = getConfService().getString(AUTO_CREATE_CUSTOMER_AFTER);
        if (StringUtils.hasText(autoCreateAfter)) {
            start = LocalDate.parse(autoCreateAfter);
        }
        if (developDate.isBefore(start)) {
            // start 之前的不自动创建
            holder.warn(entity.getName() + " 的发展日期 " + developDate + " 是 " + start + " 之前的, 按规定不自动创建客户, 如有需要请手动创建");
            return null;
        }

        CompanyCustomer companyCustomer = new CompanyCustomer();
        int nextId = SpringApp.getBean(OldVersionService.class).newCompanyCustomer(entity.getName());
        companyCustomer.setId(nextId);
        companyCustomer.setDevelopDate(developDate);
        holder.info("新客户：" + entity.getName() + "分配编号：" + nextId);
        companyCustomer.setCreated(Instant.now());
        return companyCustomer;
    }

    private Company findOrCreateCompanyByCustomerEntity(CompanyCustomerEntity entity, MessageHolder holder) {
        String name = entity.getName();
        String abbName = entity.getAbbName();
        return getCompanyCtx().findOrCreateByNameOrAbbName(name, abbName, entity.getDevelopDate(), holder);
    }

    public CompanyCustomerEntity save(CompanyCustomerEntity entity) {
        return getCustomerEntityService().save(entity);
    }


}
