package com.ecep.contract.cloud.rk;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import com.ecep.contract.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.company.repository.CompanyContactRepository;
import com.ecep.contract.ds.company.service.CompanyOldNameService;
import com.ecep.contract.model.CloudRk;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyContact;
import com.ecep.contract.model.CompanyOldName;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Data;

@Data
public class EntReportParser {
    private static final Logger logger = LoggerFactory.getLogger(EntReportParser.class);
    private ObjectMapper objectMapper;
    private Company company;
    private CloudRk cloudRk;
    private boolean modified = false;

    public void parse(JsonNode json) {
        if (!json.has("B1001")) {
            // 没有数据
            throw new RuntimeException("B1001 can't be null, json:" + json);
        }
        JsonNode b1001 = json.get("B1001");
        if (!b1001.has("count") || b1001.get("count").asInt() < 1 || !b1001.has("data")) {
            // 没有数据
            return;
        }
        JsonNode data = b1001.get("data");

        updateCompanyProperty("entType", data.get("enttype"));
        updateCompanyProperty("entStatus", data.get("entstatus"));
        updateCompanyProperty("setupDate", data.get("esdate"));

        updateCompanyUniscid(data);
        updateCompanyNameHistory(data);

        updateCompanyProperty("regAddr", data.get("dom"));
        updateCompanyProperty("registeredCapital", data.get("regcap"));
        updateCompanyProperty("registeredCapitalCurrency", data.get("regcapcur"));
        updateCompanyProperty("legalRepresentative", data.get("frname"));
        updateCompanyProperty("district", data.get("regorgprovince"));
        updateCompanyProperty("telephone", data.get("tel"));
        updateCompanyProperty("address", data.get("oploc"));
        updateCompanyProperty("operationPeriodBegin", data.get("opfrom"));
        updateCompanyProperty("operationPeriodEnd", data.get("opto"), "-");
        updateCompanyProperty("industry", data.get("nicfulltitle"));

        //
        updateCloudRkEntUpdateDate(data);

        // 更新法人联系人
        updateLegalRepresentativeContact(data);

        // 保存JSON数据到公司目录
        saveJsonToFile(json);

    }

    private void updateLegalRepresentativeContact(JsonNode data) {
        String legalRepresentative = company.getLegalRepresentative();
        if (!StringUtils.hasText(legalRepresentative)) {
            return;
        }
        CompanyContact contact = null;
        boolean modified = false;
        CompanyContactRepository contactRepository = SpringApp.getBean(CompanyContactRepository.class);
        List<CompanyContact> contactList = contactRepository.findAllByCompanyAndName(company, legalRepresentative);
        if (contactList == null) {
            // db error
            return;
        }
        if (contactList.isEmpty()) {
            // 没有，创建法人联系人
            contact = new CompanyContact();
            contact.setCompany(company);
            contact.setName(legalRepresentative);
            contact.setPosition("法定代表人");
            contact.setCreated(LocalDate.now());
            modified = true;
        } else {
            Optional<CompanyContact> any = contactList.stream().filter(c -> "法定代表人".equals(c.getPosition())).findAny();
            if (any.isEmpty()) {
                any = contactList.stream().findAny();
            }
            contact = any.get();
            // if (contact.getPostion() == null || !contact.setPostion().contains("法定代表人"))
            // {
            // contact.setMemo("法定代表人");
            // modified = true;
            // }
        }

        if (!StringUtils.hasText(contact.getEmail())) {
            String text = data.get("email").asText();
            contact.setEmail(text);
            modified = true;
        }

        if (!StringUtils.hasText(contact.getAddress())) {
            String text = company.getAddress();
            contact.setAddress(text);
            modified = true;
        }

        if (!StringUtils.hasText(contact.getPhone())) {
            String text = company.getTelephone();
            contact.setPhone(text);
            modified = true;
        }

        if (!StringUtils.hasText(contact.getPosition())) {
            contact.setPosition("法定代表人");
            modified = true;
        }

        if (modified) {
            contactRepository.save(contact);
        }

    }

    private void updateCompanyNameHistory(JsonNode data) {
        JsonNode node = data.get("nameHistory");
        if (node == null) {
            return;
        }
        // 历史曾用名
        String nameHistory = node.asText();
        if (!StringUtils.hasText(nameHistory)) {
            return;
        }
        List<String> historyNames = new ArrayList<>();
        for (String str : nameHistory.split(",")) {
            String trimmed = str.trim();
            if (StringUtils.hasText(trimmed)) {
                historyNames.add(trimmed);
            }
        }
        CompanyOldNameService service = SpringApp.getBean(CompanyOldNameService.class);
        List<CompanyOldName> oldNames = service.findAllByCompany(company);
        for (CompanyOldName oldName : oldNames) {
            historyNames.remove(oldName.getName());
        }
        for (String historyName : historyNames) {
            CompanyOldName oldName = new CompanyOldName();
            oldName.setName(historyName);
            oldName.setCompanyId(company.getId());
            oldName.setMemo("从相关方平台导入");
            oldName.setAmbiguity(false);
            service.save(oldName);
        }
    }

    private void updateCompanyUniscid(JsonNode data) {
        JsonNode node = data.get("uniscid");
        if (node == null) {
            return;
        }

        String uid = node.asText();
        if (StringUtils.hasText(uid)) {
            if (!uid.equals(company.getUniscid())) {
                if (logger.isInfoEnabled()) {
                    logger.info("更新 {} 的 UNISCID {} -> {}", company.getName(), company.getUniscid(), uid);
                }
                company.setUniscid(uid);
                modified = true;
            }
        } else {
            // fixed 当平台返回的 社会统一信用代码为空时，如果原来已经有的，则不做更新
            if (StringUtils.hasText(company.getUniscid())) {
                if (logger.isInfoEnabled()) {
                    logger.info("来自平台的 UNISCID 为空，但本地{}已经记录{}，不做更改", company.getName(), company.getUniscid());
                }
            } else {
                company.setUniscid("");
                modified = true;
            }
        }
        //
    }

    /**
     * 更新 平台的数据更新时间戳
     */
    private void updateCloudRkEntUpdateDate(JsonNode data) {
        JsonNode node = data.get("updated");
        if (node == null) {
            return;
        }
        LocalDateTime updated = objectMapper.convertValue(node, LocalDateTime.class);
        cloudRk.setCloudEntUpdate(updated);
    }

    private void updateCompanyProperty(String field, JsonNode node, String... excludeValues) {
        if (node == null || node.isNull()) {
            return;
        }
        String text = node.asText();
        for (String excludeValue : excludeValues) {
            if (Objects.equals(text, excludeValue)) {
                return;
            }
        }
        updateCompanyProperty(field, node);
    }

    /**
     * 更新属性通用方法, 数据的类型转换由 objectMapper 提供
     *
     * @param field 类属性名称
     * @param node  数据来源 json node
     */
    private void updateCompanyProperty(String field, JsonNode node) {
        if (node == null || node.isNull()) {
            return;
        }
        PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(Company.class, field);
        if (descriptor == null) {
            logger.error("Company 的字段 {} 不存在,请确认.", field);
            return;
        }
        try {
            Object oldValue = descriptor.getReadMethod().invoke(company);
            Object newValue = objectMapper.convertValue(node, descriptor.getReadMethod().getReturnType());
            if (!Objects.equals(oldValue, newValue)) {
                descriptor.getWriteMethod().invoke(company, newValue);
                modified = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void saveJsonToFile(JsonNode json) {
        String companyPath = company.getPath();
        if (StringUtils.hasText(companyPath)) {
            File dir = new File(companyPath);
            if (dir.exists()) {
                File file = new File(dir, FileUtils.FILE_B1001_JSON);
                try {
                    objectMapper.writeValue(file, json);
                } catch (IOException e) {
                    logger.warn("Unable Save BlackList to {}, company:{}", file, company.getName(), e);
                }
            }
        }
    }
}
