package com.zhongshu.card.server.core.service.devices;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.core.util.os.SystemUtil;
import com.github.microservice.models.gateDoor.use.GateDoorUseParam;
import com.github.microservice.net.ResultContent;
import com.zhongshu.card.client.model.devices.DeviceUseRecordModel;
import com.zhongshu.card.client.model.devices.DeviceUseRecordSearch;
import com.zhongshu.card.client.utils.DateUtils;
import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
import com.zhongshu.card.server.core.dao.devices.DevicePermissDao;
import com.zhongshu.card.server.core.dao.devices.DeviceUseRecordDao;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dao.org.UserCountDao;
import com.zhongshu.card.server.core.dao.school.CardInfoDao;
import com.zhongshu.card.server.core.dataConfig.TtlConfig;
import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
import com.zhongshu.card.server.core.domain.devices.DeviceUseRecords;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.domain.org.UserAccount;
import com.zhongshu.card.server.core.domain.school.CardInfo;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.projectAbout.CardInfoServiceImpl;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.server.core.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author TRX
 * @date 2024/10/21
 */
@Slf4j
@Service
public class DeviceUseRecordService extends SuperService {

    @Autowired
    private DeviceUseRecordDao deviceUseRecordDao;

    @Autowired
    protected DeviceInfoDao deviceInfoDao;

    @Autowired
    private CardInfoDao cardInfoDao;

    @Autowired
    private DevicePermissDao devicePermissDao;

    @Autowired
    private UserCountDao userCountDao;

    @Autowired
    private UserAccountServiceImpl userAccountService;

    @Autowired
    private CardInfoServiceImpl cardInfoService;

    @Autowired
    private DeviceInfoServiceImpl deviceInfoService;

    @Autowired
    private OrganizationDao organizationDao;

    //线程池
    private ExecutorService executorService = Executors.newFixedThreadPool(SystemUtil.getCpuCoreCount() * 2);

    @Autowired
    private void init(ApplicationContext applicationContext) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            executorService.shutdownNow();
        }));
    }

    /**
     * 异步保存设备使用 日志
     *
     * @param param
     */
    public void asyncSaveRecord(GateDoorUseParam param) {
        executorService.execute(() -> {
            saveDeviceLogs(param);
        });
    }

    /**
     * 设备使用日志 (物联网来的数据)
     *
     * @param param
     * @return
     */
    public ResultContent<DeviceUseRecords> saveDeviceLogs(GateDoorUseParam param) {
        // 返回数据
        String mqttDataId = param.getMqttDataId();
        DeviceUseRecords deviceUseRecord = null;
        log.info("saveDeviceUseRecord mqttDataId: {}", mqttDataId);
        if (StringUtils.isNotEmpty(mqttDataId)) {
            deviceUseRecord = init(mqttDataId);
            if (ObjectUtils.isNotEmpty(deviceUseRecord)) {
                BeanUtils.copyProperties(param, deviceUseRecord);
                String deviceId = param.getDeviceId();
                String cardNo = param.getCardNo();
                String userId = param.getUserId();
                String projectOid = "";

                DeviceInfo deviceInfo = null;
                if (StringUtils.isNotEmpty(deviceId)) {
                    deviceInfo = deviceInfoDao.findTopByDeviceId(deviceId);
                    if (ObjectUtils.isNotEmpty(deviceInfo)) {
                        projectOid = deviceInfo.getProjectOid();
                    }
                }
                // 设备信息
                deviceUseRecord.setDeviceId(deviceId);
                if (ObjectUtils.isNotEmpty(deviceInfo)) {
                    // 设备信息
                    deviceUseRecord.setDeviceInfo(deviceInfoService.toStoreModel(deviceInfo));
                    deviceUseRecord.setDeviceType(deviceInfo.getDeviceType());
                    deviceUseRecord.setGateWayId(deviceInfo.getGateWayId());
                    // 所属商户
                    deviceUseRecord.setBeLongOid(deviceInfo.getBeLongOid());
                    deviceUseRecord.setBeLongName(deviceInfo.getBeLongName());
                }

                // 卡片信息
                CardInfo cardInfo = null;
                if (StringUtils.isNotEmpty(cardNo)) {
                    cardInfo = cardInfoDao.findByCode(cardNo);
                    if (StringUtils.isEmpty(userId) && ObjectUtils.isNotEmpty(cardInfo)) {
                        userId = cardInfo.getUserId();
                    }
                }
                deviceUseRecord.setCardNo(cardNo);
                if (ObjectUtils.isNotEmpty(cardInfo)) {
                    // 卡片信息
                    deviceUseRecord.setCardInfo(cardInfoService.toStoreModel(cardInfo));
                }

                // 用户信息
                UserAccount userAccount = null;
                if (StringUtils.isNotEmpty(userId)) {
                    userAccount = userCountDao.findTopByUserId(userId);
                }
                if (ObjectUtils.isEmpty(userId)) {
                    userId = "陌生人";
                }
                deviceUseRecord.setUserId(userId);
                deviceUseRecord.setUserAccount(userAccountService.toSimpleModel(userAccount));

                // 使用时间
                if (StringUtils.isNotEmpty(param.getTime())) {
                    deviceUseRecord.setTimestamp(DateUtils.timeToLong(param.getTime(), DateUtils.FORMAT_LONG));
                }
                deviceUseRecord.setTimes();

                // 项目信息
                deviceUseRecord.setProjectOid(projectOid);
                Organization organization = organizationDao.findTopByOid(projectOid);
                if (ObjectUtils.isNotEmpty(organization)) {
                    deviceUseRecord.setProjectName(organization.getName());
                }
                deviceUseRecord.setTtl(new Date(System.currentTimeMillis() + TtlConfig.deviceUseRecordTime));
                deviceUseRecord.setMsg(param.getVerifyMsg());
                deviceUseRecordDao.save(deviceUseRecord);
            } else {
                return ResultContent.buildFail("数据初始失败");
            }
        } else {
            return ResultContent.buildFail("mqttDataId为空");
        }
        return ResultContent.buildSuccess(deviceUseRecord);
    }

    public DeviceUseRecords init(String mqttDataId) {
        DeviceUseRecords entity = deviceUseRecordDao.init(mqttDataId, TokenUtil.create());
        if (ObjectUtils.isNotEmpty(entity)) {
            entity.setCreateTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
            return entity;
        }
        return null;
    }

    public ResultContent<Page<DeviceUseRecordModel>> page(DeviceUseRecordSearch param, Pageable pageable) {
        Page<DeviceUseRecords> page = deviceUseRecordDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    public ResultContent getDetail(String id) {
        DeviceUseRecords entity = deviceUseRecordDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format("数据不存在"));
        }
        return ResultContent.buildSuccess(toModel(entity));
    }

    public ResultContent deleteById(String id) {
        DeviceUseRecords entity = deviceUseRecordDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format("数据不存在"));
        }
        deviceUseRecordDao.delete(entity);
        return ResultContent.buildSuccess();
    }

    /**
     * 模型转换
     *
     * @param entity
     * @return
     */
    public DeviceUseRecordModel toModel(DeviceUseRecords entity) {
        DeviceUseRecordModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new DeviceUseRecordModel();
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

}
