package com.ecep.contract.controller.tab;

import java.util.Map;
import java.util.logging.Level;

import org.springframework.beans.BeansException;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.model.ContractGroup;
import com.ecep.contract.model.ContractKind;
import com.ecep.contract.model.ContractType;
import com.ecep.contract.model.Employee;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.service.ContractGroupService;
import com.ecep.contract.service.ContractKindService;
import com.ecep.contract.service.ContractService;
import com.ecep.contract.service.ContractTypeService;
import com.ecep.contract.service.EmployeeService;
import com.ecep.contract.service.YongYouU8Service;
import com.ecep.contract.util.BeanCacher;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Data;
import lombok.Getter;

@Data
public class ContractUpdater implements MessageHolder {

    @lombok.Data
    static class Data {

        @Getter
        private boolean changed = false;

        private String guid;
        private String code;
        private String name;
        private String parentCode;
        private String description;
        private String typeCode;
        private String groupCode;
        private String kindName;
        private String way;
        private String unit;
        private java.sql.Date orderDate;
        private java.sql.Date startDate;
        private java.sql.Date endDate;
        private String setupPerson;
        private java.sql.Date setupDate;
        private String inurePerson;
        private java.sql.Date inureDate;
        private String varyPerson;
        private java.sql.Date varyDate;
        private Double totalCurrency;
        private String personId;

        private void setValues(ContractUpdater updater, Map<String, Object> rs) {
            guid = (String) rs.get("GUID");
            code = (String) rs.get("strContractID");
            name = (String) rs.get("strContractName");
            parentCode = (String) rs.get("strParentID");
            description = (String) rs.get("strContractDesc");
            typeCode = (String) rs.get("strContractType");
            groupCode = (String) rs.get("strContractGrp");
            kindName = (String) rs.get("strContractKind");
            way = (String) rs.get("strWay");
            unit = (String) rs.get("strBisectionUnit");
            orderDate = updater.convertValue(rs.get("strContractOrderDate"), java.sql.Date.class);
            startDate = updater.convertValue(rs.get("strContractStartDate"), java.sql.Date.class);
            endDate = updater.convertValue(rs.get("strContractEndDate"), java.sql.Date.class);
            setupPerson = (String) rs.get("strSetupPerson");
            setupDate = updater.convertValue(rs.get("strSetupDate"), java.sql.Date.class);
            inurePerson = (String) rs.get("strInurePerson");
            inureDate = updater.convertValue(rs.get("strInureDate"), java.sql.Date.class);
            varyPerson = (String) rs.get("strVaryPerson");
            varyDate = updater.convertValue(rs.get("dtVaryDate"), java.sql.Date.class);
            totalCurrency = (Double) rs.get("dblTotalCurrency");
            personId = (String) rs.get("strPersonID");
        }

        private void changed() {
            changed = true;
        }
    }

    public static ContractUpdater with(MessageHolder holder) {
        ContractUpdater updater = new ContractUpdater();
        updater.holder = holder;
        return updater;
    }

    private BeanCacher beanCacher = new BeanCacher();

    private MessageHolder holder;

    public <T> T convertValue(Object fromValue, Class<T> toValueType) throws IllegalArgumentException {
        return getObjectMapper().convertValue(fromValue, toValueType);
    }

    @Override
    public void addMessage(Level level, String message) {
        holder.addMessage(level, message);
    }

    public void updateMessage(String message) {
        MessageHolder consumer = getHolder();
        if (consumer != null) {
            consumer.info(message);
        }
    }

    <T> T getBean(Class<T> requiredType) throws BeansException {
        return beanCacher.getBean(requiredType);
    }

    private ObjectMapper getObjectMapper() {
        return getBean(ObjectMapper.class);
    }

    private ContractService getContractService() {
        return getBean(ContractService.class);
    }

    private EmployeeService getEmployeeService() {
        return getBean(EmployeeService.class);
    }

    private ContractType getTypeByCode(String typeCode) {
        ContractType type = getBean(ContractTypeService.class).findByCode(typeCode);
        return type;
    }

    private ContractGroup getGroupByCode(String groupCode) {
        ContractGroup group = getBean(ContractGroupService.class).findByCode(groupCode);
        return group;
    }

    private ContractKind getKindByName(String kindName) {
        ContractKind kind = getBean(ContractKindService.class).findByName(kindName);
        return kind;
    }

    private Employee findEmployeeByCode(String personCode) {
        return getEmployeeService().findByCode(personCode);
    }

    private Employee findEmployeeByName(String personName) {
        if (personName == null) {
            return null;
        }
        return getEmployeeService().findByName(personName);
    }

    private CompanyVendorService getVendorService() {
        return getBean(CompanyVendorService.class);
    }

    private CompanyCustomerService getCustomerService() {
        return getBean(CompanyCustomerService.class);
    }

    private CompanyService getCompanyService() {
        return getBean(CompanyService.class);
    }

    private YongYouU8Service getU8Service() {
        return getBean(YongYouU8Service.class);
    }

}
