package com.ecep.contract.cloud.u8;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.ecep.contract.ContractPayWay;

import javax.sql.DataSource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

@Lazy
@Repository
@ConditionalOnBean(YongYouU8Service.class)
public class YongYouU8Repository {
    private JdbcTemplate jdbcTemplate;
    @Lazy
    @Autowired
    @Qualifier("MSSQL_Server")
    private DataSource dataSource;

    private JdbcTemplate getJdbcTemplate() {
        if (jdbcTemplate == null) {
            jdbcTemplate = new JdbcTemplate(dataSource);
        }
        return jdbcTemplate;
    }


    /**
     * 返回 U8 系统中 供应商总数
     *
     * @return 供应商总数
     */
    public Long countAllVendors() {
        return getJdbcTemplate().queryForObject("select count(*) from Vendor", Long.class);
    }

    /**
     * 以流式返回所有供应商数据
     *
     * @return Stream 数据流
     */
    public Stream<Map<String, Object>> queryAllVendorForStream() {
        return getJdbcTemplate().queryForStream(
                "select cVenCode,cVenName,cVenAbbName," +
                        "cVCCode,cVenAddress,cast(dVenDevDate as DATE) as venDevDate," +
                        "cVenBank, cVenAccount, cCreatePerson,cModifyPerson,dModifyDate " +
                        "from Vendor",
                new ColumnMapRowMapper()
        );
    }


    /**
     * 以 U8 供应商 的代码查询 供应商
     *
     * @param vendCode U8 供应商 的代码，vendCode 唯一
     * @return 字段和值的Map集合, 没找到匹配的记录时，返回null
     */
    public Map<String, Object> findVendorByVendCode(String vendCode) {
        try {
            return getJdbcTemplate().queryForObject("select cVenCode,cVenName,cVenAbbName," +
                    "cVCCode,cVenAddress," +
                    "cast(dVenDevDate as DATE) as devDate,dModifyDate," +
                    "cVenBank,cVenAccount,cCreatePerson, cModifyPerson " +
                    "from Vendor where cVenCode=?", new ColumnMapRowMapper(), vendCode);
        } catch (EmptyResultDataAccessException e) {
            return null;
        } catch (Exception e) {
            throw new RuntimeException(vendCode, e);
        }
    }

    /**
     * 返回 U8 系统中 客户总数
     *
     * @return 客户总数
     */
    public Long countAllCustomers() {
        return getJdbcTemplate().queryForObject("select count(*) from Customer", Long.class);
    }

    /**
     * 以流式返回所有客户数据
     *
     * @return Stream 数据流
     */
    public Stream<Map<String, Object>> queryAllCustomerForStream() {
        return getJdbcTemplate().queryForStream(
                "select cCusCode,cCusName,cCusAbbName," +
                        "cCCCode,cCusAddress,cast(dCusDevDate as DATE) as cusDevDate," +
                        "cCusBank,cCusAccount, cCreatePerson,cModifyPerson,dModifyDate " +
                        "from Customer",
                new ColumnMapRowMapper()
        );
    }

    /**
     * 以 U8 客户 的代码查询 客户
     *
     * @param cusCode U8 客户 的代码，cusCode 唯一
     * @return 字段和值的Map集合
     */
    public Map<String, Object> findCustomerByCusCode(String cusCode) {
        return getJdbcTemplate().queryForObject("select cCusCode,cCusName,cCusAbbName," +
                "cCCCode,cCusAddress," +
                "cast(dCusDevDate as DATE) as devDate,dModifyDate," +
                "cCusBank,cCusAccount,cCreatePerson,cModifyPerson " +
                "from Customer where cCusCode=?", new ColumnMapRowMapper(), cusCode);
    }

    /**
     * 返回 U8 系统中 合同总数
     * 在U8中合同在多个地方存在，CM_List， CM_Contract_A,CM_Contract_B,CM_Contract_C
     *
     * @return 合同总数
     */
    public Long countAllContracts(int latestId) {
        return getJdbcTemplate().queryForObject("select count(*) from CM_List where ID>?", Long.class, latestId);
    }

    public Long countAllContracts(LocalDateTime dateTime) {
        return getJdbcTemplate().queryForObject("select count(*) from CM_List where dtDate>?", Long.class, dateTime);
    }

    public Long countAllContracts() {
        return getJdbcTemplate().queryForObject("select count(*) from CM_List", Long.class);
    }

    public Long countAllContractB() {
        return getJdbcTemplate().queryForObject("select count(*) from CM_Contract_B", Long.class);
    }

    public Long countAllContractB(LocalDate latestDate) {
        return getJdbcTemplate().queryForObject(
                "select count(*) " +
                        "from CM_Contract_B " +
                        "where strSetupDate>=? or (dtVaryDate is not null and dtVaryDate>=?)"
                , Long.class, latestDate, latestDate);
    }

    public Stream<Map<String, Object>> queryAllContractForStream() {
        return getJdbcTemplate().queryForStream(
                "select * from CM_List", new ColumnMapRowMapper()
        );
    }

    public Stream<Map<String, Object>> queryAllContractForStream(int latestId) {
        return getJdbcTemplate().queryForStream(
                "select * from CM_List where ID > ?",
                new ColumnMapRowMapper(),
                latestId
        );
    }

    public Stream<Map<String, Object>> queryAllContractForStream(LocalDateTime dateTime) {
        return getJdbcTemplate().queryForStream(
                "select * from CM_List where dtDate > ?",
                new ColumnMapRowMapper(),
                dateTime
        );
    }

    public Stream<Map<String, Object>> queryAllContractBForStream() {
        return getJdbcTemplate().queryForStream(
                "select GUID,strContractID,strContractName,strContractType,strParentID,strContractKind,strWay," +
                        "strContractGrp,strContractDesc,strBisectionUnit," +
                        // 时间
                        "strContractOrderDate,strContractStartDate,strContractEndDate," +
                        // 创建人和时间
                        "strSetupPerson,strSetupDate," +
                        // 生效人和时间
                        "strInurePerson,strInureDate," +
                        // 修改人和时间
                        "strVaryPerson,dtVaryDate," +
                        // 业务员
                        "strPersonID, " +
                        "dblTotalCurrency,dblExecCurrency,dblTotalQuantity,dblExecQuqantity " +
                        "from CM_Contract_B ",
                new ColumnMapRowMapper()
        );
    }

    public Stream<Map<String, Object>> queryAllContractBForStream(LocalDate latestDate) {
        return getJdbcTemplate().queryForStream(
                "select GUID,strContractID,strContractName,strContractType,strParentID,strContractKind,strWay," +
                        "strContractGrp,strContractDesc,strBisectionUnit," +
                        // 时间
                        "strContractOrderDate,strContractStartDate,strContractEndDate," +
                        // 创建人和时间
                        "strSetupPerson,strSetupDate," +
                        // 生效人和时间
                        "strInurePerson,strInureDate," +
                        // 修改人和时间
                        "strVaryPerson,dtVaryDate," +
                        // 业务员
                        "strPersonID, " +
                        "dblTotalCurrency,dblExecCurrency,dblTotalQuantity,dblExecQuqantity " +
                        "from CM_Contract_B where strSetupDate>=? or (dtVaryDate is not null and dtVaryDate>=?)",
                new ColumnMapRowMapper(), latestDate, latestDate
        );
    }

    /**
     * 从 CM_Contract_B 表中，检索 strBisectionUnit 是 unit 的记录
     *
     * @param unit   单位编码
     * @param payWay 付款方向，付 或 收
     */
    public Stream<Map<String, Object>> queryAllContractByUnitForStream(String unit, ContractPayWay payWay) {
        return getJdbcTemplate().queryForStream(
                "select GUID,strContractID,strContractName,strContractType,strParentID,strContractKind,strWay," +
                        "strContractGrp, strContractDesc,strBisectionUnit," +
                        // 时间
                        "strContractOrderDate,strContractStartDate,strContractEndDate," +
                        // 创建人和时间
                        "strSetupPerson,strSetupDate," +
                        // 生效人和时间
                        "strInurePerson,strInureDate," +
                        // 修改人和时间
                        "strVaryPerson,dtVaryDate," +
                        // 业务员
                        "strPersonID, " +
                        "dblTotalCurrency,dblExecCurrency,dblTotalQuantity,dblExecQuqantity " +
                        "from CM_Contract_B where strBisectionUnit=? and strWay=?",
                new ColumnMapRowMapper(), unit, payWay.getText()
        );
    }

    public Map<String, Object> queryContractDetail(String guid) {
        return getJdbcTemplate().queryForObject("select GUID,strContractID,strContractName,strContractType,strParentID,strContractKind,strWay," +
                "strContractGrp, strContractDesc,strBisectionUnit," +
                // 时间
                "strContractOrderDate,strContractStartDate,strContractEndDate," +
                // 创建人和时间
                "strSetupPerson,strSetupDate," +
                // 生效人和时间
                "strInurePerson,strInureDate," +
                // 修改人和时间
                "strVaryPerson,dtVaryDate," +
                // 业务员
                "strPersonID, " +
                "dblTotalCurrency,dblExecCurrency,dblTotalQuantity,dblExecQuqantity " +
                " from CM_Contract_B where GUID = ?", new ColumnMapRowMapper(), guid);
    }

    /**
     * 合计合同的执行数量、金额、 不含税金额
     *
     * @param code 合同号
     * @return Map<String, Object>
     */
    public Map<String, Object> sumContractExec(String code) {
        return getJdbcTemplate().queryForObject("select sum(decCount) as execQuantity, sum(decRateMoney) as execAmount, sum(decNoRateMoney) as execUnTaxAmount " +
                "from CM_ExecInterface " +
                "where cContractID = ?;", new ColumnMapRowMapper(), code);
    }

    public List<Map<String, Object>> findAllContractExecByContractCode(String code) {
        return getJdbcTemplate().queryForList("select * from CM_ExecInterface where cContractID=?", code);
    }

    public List<Map<String, Object>> findAllContractItemByContractCode(String code) {
        return getJdbcTemplate().queryForList("select * from CM_Contract_Item_B where strContractID=?", code);
    }

    public List<Map<String, Object>> findAllContractPayPlanByContractCode(String code) {
        return getJdbcTemplate().queryForList("select * from CM_Contract_Pay where strContractID=?", code);
    }

    public Map<String, Object> querySalesOrderDetail(String code) {
        return getJdbcTemplate().queryForObject("select * " +
                " from SO_SOMain where cSOCode = ?", new ColumnMapRowMapper(), code);
    }

    public List<Map<String, Object>> findAllSalesOrderItemByContractCode(String code) {
        return getJdbcTemplate().queryForList("select * from SO_SODetails where cContractID=?", code);
    }

    public Map<String, Object> queryPurchaseOrderDetail(Integer code) {
        return getJdbcTemplate().queryForObject("select * " +
                " from PO_Pomain where POID = ?", new ColumnMapRowMapper(), code);
    }


    /**
     * 采购合同项
     *
     * @param code 采购合同号
     * @return List<Map < String, Object>>
     */
    public List<Map<String, Object>> findAllPurchaseOrderItemByContractCode(String code) {
        return getJdbcTemplate().queryForList("select * from PO_Podetails where ContractCode=?", code);
    }

    /**
     * 查询存货档案数据
     *
     * @param code 存货编码
     * @return Map<String, Object>
     */
    public Map<String, Object> queryInventoryDetail(String code) {
        return getJdbcTemplate().queryForObject("select I.*, U.cComUnitName from Inventory as I left join ComputationUnit as U on I.cComUnitCode=U.cComunitCode where cInvCode = ?", new ColumnMapRowMapper(), code);
    }

    public List<Map<String, Object>> queryAllPerson() {
        return getJdbcTemplate().queryForList("select *  from Person;");
    }

    public List<Map<String, Object>> queryAllContractGroup() {
        return getJdbcTemplate().queryForList("select cGroupID, cGroupName,cRemark from CM_Group;");
    }

    public List<Map<String, Object>> queryAllContractType() {
        return getJdbcTemplate().queryForList(
                "select cTypeCode, cTypeName, CM_TypeClass.cClassName, cCharacter, cDirection " +
                        "from CM_Type left join CM_TypeClass on CM_Type.cClassCode = CM_TypeClass.cClassCode;");
    }

    public List<Map<String, Object>> queryAllContractKind() {
        return getJdbcTemplate().queryForList("select KindID,KindName,Description from CM_Kind;");
    }

    public List<Map<String, Object>> queryAllVendorClass() {
        return getJdbcTemplate().queryForList("select cVCCode, cVCName, iVCGrade from VendorClass;");
    }

    public List<Map<String, Object>> queryAllCustomerClass() {
        return getJdbcTemplate().queryForList("select cCCCode, cCCName, iCCGrade from CustomerClass;");
    }


    public List<Map<String, Object>> findAllPurchaseBillVoucherByVendorCode(String code) {
        return getJdbcTemplate().queryForList("select * from PurBillVouch where cVenCode=?", code);
    }

    public Map<String, Object> findPurchaseBillVoucherById(Integer pbvId) {
        return getJdbcTemplate().queryForObject("select * from PurBillVouch where PBVID = ?", new ColumnMapRowMapper(), pbvId);
    }

    public List<Map<String, Object>> findAllPurchaseBillVoucherItemByPbvId(int pbvId) {
        return getJdbcTemplate().queryForList("select * from PurBillVouchs where PBVID=?", pbvId);
    }

    /**
     * 通过合同编号查询采购
     *
     * @param contractCode 合同编号
     */
    public List<Map<String, Object>> findAllPurchaseBillVoucherItemByContractCode(String contractCode) {
        return getJdbcTemplate().queryForList("select * from PurBillVouchs where ContractCode=?", contractCode);
    }

    public List<Map<String, Object>> findAllSalesBillVoucherByCustomerCode(String code) {
        return getJdbcTemplate().queryForList("select * from SaleBillVouch where cCusCode=?", code);
    }

    public List<Map<String, Object>> findAllSalesBillVoucherBySalesOrderCode(String code) {
        return getJdbcTemplate().queryForList("select * from SaleBillVouch where cSOCode=?", code);
    }

    public List<Map<String, Object>> findAllSalesBillVoucherItemBySBVID(int sbvid) {
        return getJdbcTemplate().queryForList("select * from SaleBillVouchs where SBVID=?", sbvid);
    }



}
