package com.bcxin.tenant.open.domains.utils;

import com.bcxin.tenant.open.domains.dtos.RoomCommunicatedGroupDTO;
import com.bcxin.tenant.open.domains.entities.ConfigOfBillEntity;
import com.bcxin.tenant.open.domains.entities.MonthlyBillEntity;
import com.bcxin.tenant.open.domains.entities.OrgPurseTransactionEntity;
import com.bcxin.tenant.open.infrastructures.components.IdWorker;
import com.bcxin.tenant.open.infrastructures.components.JsonProvider;
import com.bcxin.tenant.open.infrastructures.enums.CommunicatedType;
import com.bcxin.tenant.open.infrastructures.utils.StringUtil;
import com.bcxin.tenant.open.infrastructures.enums.BillPaymentStatus;
import com.bcxin.tenant.open.infrastructures.enums.PointChangeType;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

public class OrgPurseTransactionUtil {
    public static Collection<OrgPurseTransactionEntity> build(
            IdWorker idWorker,
            Collection<RoomCommunicatedGroupDTO> communicatedGroups,
            JsonProvider jsonProvider,
            ConfigOfBillEntity config
    ) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Collection<OrgPurseTransactionEntity> orgPurseTransactions = new ArrayList<>();
        for (RoomCommunicatedGroupDTO group : communicatedGroups) {
            /**
             * todo: 调度人不扣联动值
             * todo: 后续需要针对湖南的进行计算
             */
            List<RoomCommunicatedGroupDTO.JoinRoomUserDto> joinRoomUsers = group.getJoinRoomUsers()
                    .stream().filter(ix -> !ix.isCaller())
                    .collect(Collectors.toList());
            for (RoomCommunicatedGroupDTO.AudioVideoLogDto audioVideoLog : group.getAudioVideoLogs()) {
                for (int index = 0; index < joinRoomUsers.size(); index++) {

                    RoomCommunicatedGroupDTO.JoinRoomUserDto roomUser = joinRoomUsers.get(index);
                    /**
                     * 有加入该音视频的人才需要计算联动值
                     */
                    if (audioVideoLog.HasJoin(roomUser)) {
                        long pkId = idWorker.getNextId();
                        Map<String, Object> map = new HashMap<>();
                        map.put("vgaId", audioVideoLog.getId());
                        map.put("beginTime", dateFormat.format(audioVideoLog.getActuallyBeginJoinTime(roomUser)));
                        map.put("endTime", dateFormat.format(audioVideoLog.getActuallyEndJoinTime(roomUser)));
                        map.put("invitedTime", dateFormat.format(roomUser.getCreatedTime()));
                        map.put("roomId", group.getRoomId());
                        map.put("v", "2");
                        String json = jsonProvider.getJson(map);

                        String purseTransactionDomainId = roomUser.getDomainId();
                        String purseTransactionDomainName = roomUser.getCompanyName();
                        if(group.isCallerPayTheBill()) {
                            purseTransactionDomainId = group.getCallerCompanyId();
                            purseTransactionDomainName = group.getCallerCompanyName();
                        }

                        OrgPurseTransactionEntity transaction =
                                OrgPurseTransactionEntity.create(
                                        pkId,
                                        String.valueOf(roomUser.getInvitedUserRecordId()),
                                        purseTransactionDomainId,
                                        purseTransactionDomainName,
                                        audioVideoLog.getChangeType(),
                                        /**
                                         * 音视频房间号
                                         */
                                        String.valueOf(roomUser.getInvitedUserRecordId()),
                                        /**
                                         * 对应的调度记录的前缀Id
                                         */
                                        json,
                                        roomUser.getEmployeeName(),
                                        roomUser.getEmployeeId(),
                                        PointUtils.translate2Points(
                                                config,
                                                audioVideoLog.getChangeType(),
                                                audioVideoLog.getActuallyBeginJoinTime(roomUser),
                                                audioVideoLog.getActuallyEndJoinTime(roomUser)),
                                        audioVideoLog.getActuallyBeginJoinTime(roomUser)
                                );
                        orgPurseTransactions.add(transaction);
                    }
                }
            }

            /**
             * 调度类型;
             * 找不到的时候, 按照音频来计费; 有视频就按照视频
             */
            CommunicatedType communicatedType = group.getCommunicatedType();
            if (communicatedType != null) {
                for (RoomCommunicatedGroupDTO.NoAnswerRoomUserRecordDto noAnswerRoomUserRecord : group.getNoAnswerRoomUsers()) {
                    long pkId = idWorker.getNextId();
                    Map<String, Object> map = new HashMap<>();
                    map.put("roomId", group.getRoomId());
                    map.put("invitedTime", dateFormat.format(noAnswerRoomUserRecord.getCreatedTime()));
                    map.put("v", "2");
                    map.put("type", "np");
                    String json = jsonProvider.getJson(map);

                    String purseTransactionDomainId = noAnswerRoomUserRecord.getDomainId();
                    String purseTransactionDomainName = noAnswerRoomUserRecord.getCompanyName();
                    if(group.isCallerPayTheBill()) {
                        purseTransactionDomainId = group.getCallerCompanyId();
                        purseTransactionDomainName = group.getCallerCompanyName();
                    }

                    OrgPurseTransactionEntity transaction =
                            OrgPurseTransactionEntity.create(
                                    pkId,
                                    String.valueOf(noAnswerRoomUserRecord.getId()),
                                    purseTransactionDomainId,
                                    purseTransactionDomainName,
                                    communicatedType == CommunicatedType.Video ? PointChangeType.VideoCost : PointChangeType.AudioCost,
                                    /**
                                     * 对应的调度记录的前缀Id
                                     */
                                    String.valueOf(noAnswerRoomUserRecord.getId()),
                                    /**
                                     * 音视频的Id
                                     */
                                    json,
                                    noAnswerRoomUserRecord.getEmployeeName(),
                                    noAnswerRoomUserRecord.getEmployeeId(),
                                    -1,
                                    noAnswerRoomUserRecord.getCreatedTime()
                            );

                    orgPurseTransactions.add(transaction);
                }
            }
        }

        return orgPurseTransactions;
    }

    public static Collection<OrgPurseTransactionEntity> build(IdWorker idWorker,
                                                              Collection<MonthlyBillEntity> billEntities,
                                                              JsonProvider jsonProvider){
        Collection<OrgPurseTransactionEntity> orgPurseTransactions =
                billEntities.stream().filter(ix->!ix.getBillPaymentStatus().equals(BillPaymentStatus.Paid)&& ix.getIsReady() == 1)
                .map(ix->{
            long pkId = idWorker.getNextId();
            Map<String, Object> map = new HashMap<>();
            map.put("billId", ix.getBillId());
            map.put("billType", ix.getBillType());
            map.put("status", ix.getBillPaymentStatus());
            map.put("amount", ix.getAmount());
            map.put("paidAmount", ix.getPaidAmount());
            String json = jsonProvider.getJson(map);
            OrgPurseTransactionEntity transaction = OrgPurseTransactionEntity.create(
                    pkId,
                    String.valueOf(pkId),
                    ix.getOrgId(),
                    null,
                    PointChangeType.BillCharge,
                    ix.getBillId(),
                    json,
                    null,
                    null,
                    ix.getPaidAmount() - ix.getAmount(),
                    Timestamp.from(Instant.now())

            );
            return transaction;
        }).collect(Collectors.toList());

        return orgPurseTransactions;
    }

    public static OrgPurseTransactionEntity build(IdWorker idWorker,
                                                              MonthlyBillEntity billEntitie,
                                                              JsonProvider jsonProvider, Long orgPursePoint, String orgName){
        long pkId = idWorker.getNextId();
        Instant currentInstant = Instant.now();
        long currentSeconds = currentInstant.getEpochSecond();
        Map<String, Object> map = new HashMap<>();
        map.put("billId", billEntitie.getBillId());
        map.put("billType", billEntitie.getBillType());
        map.put("status", billEntitie.getBillPaymentStatus());
        map.put("amount", billEntitie.getAmount());
        map.put("orgPurseRemainPoint",orgPursePoint);
        map.put("paidAmount", billEntitie.getPaidAmount());
        String json = jsonProvider.getJson(map);
        OrgPurseTransactionEntity transaction = OrgPurseTransactionEntity.create(
                pkId,
                String.valueOf(pkId),
                billEntitie.getOrgId(),
                orgName,
                PointChangeType.BillCharge,
                billEntitie.getBillId().concat("-").concat(String.valueOf(currentSeconds)),
                json,
                null,
                null,
                0 - Math.min(orgPursePoint.intValue(),billEntitie.getAmount() - billEntitie.getPaidAmount()),
                Timestamp.from(Instant.now())
        );
        return transaction;

    }
}
