package com.zcloud.personnel.positioning.command;

import com.alibaba.cola.exception.BizException;
import com.zcloud.personnel.positioning.command.query.TerminalAppQueryExe;
import com.zcloud.personnel.positioning.domain.model.TerminalE;
import com.zcloud.personnel.positioning.dto.TerminalAppSaveCmd;
import com.zcloud.personnel.positioning.dto.clientobject.TerminalAppCO;
import com.zcloud.personnel.positioning.persistence.dataobject.CorpInfoSnapshotDO;
import com.zcloud.personnel.positioning.persistence.dataobject.TerminalPersonSnapshotDO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Component
@AllArgsConstructor
public class TerminalAppAddExe {
    private final TerminalBindingService terminalBindingService;
    private final FindsPendingSyncService findsPendingSyncService;
    private final TerminalAppQueryExe terminalAppQueryExe;

    @Transactional(rollbackFor = Exception.class)
    public TerminalAppCO execute(TerminalAppSaveCmd cmd) {
        if (cmd == null || !StringUtils.hasText(cmd.getAppAccount())) {
            throw new BizException("APP account is required");
        }
        String appAccount = cmd.getAppAccount().trim();
        String terminalNo = resolveTerminalNo(cmd.getTerminalNo(), appAccount);
        if (terminalBindingService.findTerminalByNo(terminalNo) != null
                || terminalBindingService.findAppByAccount(appAccount) != null) {
            throw new BizException("APP account or terminal no already exists");
        }
        CorpInfoSnapshotDO corpInfo = terminalBindingService.resolveCorpInfo(cmd.getCorpinfoId(),
                cmd.getCorpinfoName(), cmd.getOrgCode(), cmd.getOrgName());
        TerminalE terminal = new TerminalE();
        terminal.setTerminalNo(terminalNo);
        terminal.setTerminalName(firstText(cmd.getTerminalName(), appAccount));
        terminal.setDeviceType("APP");
        terminal.setAppAccount(appAccount);
        terminal.setCorpinfoId(corpInfo == null ? cmd.getCorpinfoId() : corpInfo.getCorpinfoId());
        terminal.setCorpinfoName(firstText(cmd.getCorpinfoName(),
                corpInfo == null ? null : corpInfo.getCorpName(), cmd.getOrgName()));
        terminal.setOrgCode(firstText(cmd.getOrgCode(), corpInfo == null ? null : corpInfo.getCreditCode()));
        terminal.setOrgName(firstText(cmd.getOrgName(), terminal.getCorpinfoName()));
        terminal.setEnable(cmd.getEnable() == null ? 1 : cmd.getEnable());
        terminal.setSyncStatus(FindsPendingSyncService.STATUS_WAIT);
        terminal.setSyncToken(FindsSyncToken.next());
        terminal.setRemarks(cmd.getRemarks());
        terminalBindingService.addTerminal(terminal);
        TerminalPersonSnapshotDO person = terminalBindingService.resolvePerson(cmd.getBindIdCardNo(),
                cmd.getStaffNo(), cmd.getStaffName());
        if (person != null) {
            terminalBindingService.upsertActiveBinding(terminal, person, true, LocalDateTime.now());
        }
        findsPendingSyncService.scheduleTerminal(terminal.getId());
        return terminalAppQueryExe.queryAppById(terminal.getId());
    }

    private String resolveTerminalNo(String terminalNo, String appAccount) {
        String result = firstText(terminalNo, appAccount);
        if (!StringUtils.hasText(result)) throw new BizException("FindS terminal no is required");
        return result.trim();
    }

    private String firstText(String... values) {
        for (String value : values) if (StringUtils.hasText(value)) return value;
        return null;
    }
}
