package com.liquidnet.service.adam.service.processor;

import com.liquidnet.service.adam.dto.vo.AdamAddressesVo;
import com.liquidnet.service.adam.entity.AdamAddresses;
import com.liquidnet.service.adam.service.DataMigrationProcessorService;
import com.liquidnet.service.adam.service.IAdamAddressesService;
import com.mysql.cj.jdbc.result.ResultSetImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class DMAddressesProcessor extends DataMigrationProcessorService {
    @Autowired
    IAdamAddressesService adamAddressesService;

    @SneakyThrows
    @Override
    public void dataProcessing(Integer dg, Integer dG, String incrDt, String flg, String flu) {
        if (StringUtils.isNotEmpty(flu)) {
            log.info("DM.flush.addresses:{}", userMapper.executeForDM("adam_addresses"));
            log.info("DM.flush.AdamAddressesVo:{}", mongoTemplate.remove(Query.query(Criteria.where("_id").exists(true)), AdamAddressesVo.class.getSimpleName()).getDeletedCount());
        }

        String sqlCount = "select count(1) from addresses where created_at" + (StringUtils.isBlank(incrDt) ? "<" : ">=") + "curdate()";
        if (null != dg) {
            sqlCount = sqlCount + " and id%" + dG + "=" + dg;
        }
        String field = "id,user_id,user_name,user_phone,province,city,county,user_address,defaultDelivery,created_at";
//                     1-id,2-user_id,3-user_name,4-user_phone,5-province,6-city,7-county,8-user_address,9-defaultDelivery,10-created_at
        String sql = sqlCount.replace("count(1)", field);
        if ("1".equals(flg)) {
            sqlCount += " and user_id in ('2026628','544327','1997335','773650','809406','1167451','423063','677171')";
            sql += " and user_id in ('2026628','544327','1997335','773650','809406','1167451','423063','677171')";
        }
        sql += " order by id limit ?,?";

        Class.forName(DB_DRIVER);
        Connection connection = DriverManager.getConnection(DB_URL + DB_NAME_MALL, DB_USER, DB_PWD);

        PreparedStatement statement = connection.prepareStatement(sqlCount);
        ResultSetImpl row = (ResultSetImpl) statement.executeQuery();
        row.first();
        int ct = row.getInt(1), pSize = 1000, num = 0, tl = 0, pl = ct;
        log.info("DM.execute.counts:{}/{},{} ~ {} ----------------------------> start.sql:{}", pl, num, pSize, tl, sql);

        while (ct > 0) {
            statement = connection.prepareStatement(sql);
            int ls = pSize * num;
            statement.setInt(1, ls);
            statement.setInt(2, pSize);
            row = (ResultSetImpl) statement.executeQuery();
            log.info("DM.execute.limit {},{} - begin", ls, pSize);

            List<AdamAddresses> addressesList = new ArrayList<>();
            List<AdamAddressesVo> vos = new ArrayList<>();
            while (row.next()) {
                String uid = row.getString(2);

                if (!reUidList.contains(uid)) {
                    AdamAddresses addresses = new AdamAddresses();
                    addresses.setAddressesId(row.getString(1));
                    addresses.setUid(uid);
                    addresses.setName(row.getString(3));
                    addresses.setPhone(row.getString(4));
                    addresses.setProvince(row.getString(5));
                    addresses.setCity(row.getString(6));
                    addresses.setCounty(row.getString(7));
                    addresses.setAddress(row.getString(8));
                    addresses.setIsDefault(row.getBoolean(9));
                    addresses.setState(1);
                    addresses.setCreatedAt(row.getLocalDateTime(10));

                    AdamAddressesVo vo = AdamAddressesVo.getNew().copy(addresses);

                    addressesList.add(addresses);
                    vos.add(vo);
                }
            }
            log.info("DM.execute.limit {},{} - handle.counts:{}", ls, pSize, addressesList.size());
            if (!CollectionUtils.isEmpty(addressesList)) {
                tl += addressesList.size();
                mongoTemplate.insert(vos, AdamAddressesVo.class.getSimpleName());
                log.info("DM.execute.limit.result:{}", adamAddressesService.saveBatch(addressesList));
            }

            num++;
            ct -= pSize;
        }
        log.info("DM.execute.counts:{}/{},{} ~ {} ----------------------------> end", pl, num, pSize, tl);
        row.close();
        statement.close();
        connection.close();
    }
}
