package com.dtok.api.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.generator.UUIDGenerator;
import com.dtok.entity.Account;
import com.dtok.entity.Devices;
import com.dtok.entity.Script;
import com.dtok.framework.exception.AuthenticateException;
import com.dtok.framework.response.ResponseData;
import com.dtok.framework.util.IpUtil;
import com.dtok.framework.util.ToolUtil;
import com.dtok.repository.AccountRepository;
import com.dtok.repository.DevicesRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/device")
public class DeviceController {

    @Autowired
    DevicesRepository devicesRepository;


    @Autowired
    AccountRepository accountRepository;

    @PostMapping("/search")
    public ResponseData search() {
        Specification<Devices> query = (root, query1, criteriaBuilder) -> {

            Predicate predicate = criteriaBuilder.conjunction();
            Account account = ((Account) StpUtil.getSession().get("loginUser"));
            if (!account.getIsSuper()) {
                predicate.getExpressions().add(criteriaBuilder.or(criteriaBuilder.equal(root.get("account"), account.getId())));
            }
            return predicate;
        };
        List<Devices> result = devicesRepository.findAll(query);
        return ResponseData.success(result);
    }

    @PostMapping("/registerDevice/{token}")
    public ResponseData registerDevice(Devices devices, @PathVariable String token) {
        String username = (String) StpUtil.getLoginIdByToken(token);
        if (!StpUtil.getTokenValue().equals(token)) {
            throw new AuthenticateException(401, "非法注册");
        }
        if (!StringUtils.hasLength(username)) {
            throw new AuthenticateException(401, "登录信息失效");
        }
        if (!StringUtils.hasLength(devices.getDeviceBrand())) {
            throw new AuthenticateException(404, "注册信息缺失");
        }
        if (!StringUtils.hasLength(devices.getDeviceName())) {
            throw new AuthenticateException(404, "注册信息缺失");
        }
        if (!StringUtils.hasLength(devices.getDeviceVersion())) {
            throw new AuthenticateException(404, "注册信息缺失");
        }
        if (!StringUtils.hasLength(devices.getAndroidId())) {
            throw new AuthenticateException(404, "注册信息缺失");
        }


        Account account = accountRepository.getUserLoginEntity(username);

        List<Devices> devicesList = devicesRepository.searchAllByAccountUsername(username);

        Integer alreadyRegister = devicesRepository.countByAndroidId(devices.getAndroidId());


        if (alreadyRegister > 0) {
            throw new AuthenticateException(403, "设备已注册,请解绑");
        }


        if (devicesList.stream().anyMatch(obj -> obj.getAndroidId().equals(devices.getAndroidId()))) {
            throw new AuthenticateException(403, "设备已注册");
        }


        if (account.getMaxDevices() <= devicesList.size()) {
            throw new AuthenticateException(402, "已达到最大设备数量");
        }

        devices.setUuid(new UUIDGenerator().next());
        devices.setAccount(account.getId());
        devices.setLastConnectionIp(IpUtil.getRequestIp());
        devices.setLastConnectionTime(new DateTime());
        devices.setStatus(Devices.OFFLINE);
        devices.setRegisterAt(new Date());
        devicesRepository.save(devices);

        return ResponseData.success(devices);
    }

    @GetMapping("/unBundleDevice/{id}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseData unBundleDevice(@PathVariable String id) {
        if (!StringUtils.hasLength(id)) throw new NullPointerException("id参数不能为空");
        Devices devices = devicesRepository.findFirstByUuid(id);
        if (Objects.isNull(devices)) {
            throw new NullPointerException("没找到设备");
        }
        Account account = (Account) StpUtil.getSession().get("loginUser");
        if (!account.getId().equals(devices.getAccount())) {
            throw new AuthenticateException(403, "不是你的设备");
        }
        devicesRepository.deleteDevicesByUuid(id);
        return ResponseData.success("解绑完成");
    }


}
