package com.sptg.permissions.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.sptg.common.core.beans.PageBean;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.UserFlagConstant;
import com.sptg.common.core.util.CommonUtil;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.vo.DeviceVO;
import com.sptg.permissions.api.constant.ConfTokenName;
import com.sptg.permissions.api.dto.AccountDto;
import com.sptg.permissions.api.dto.AccountRoleDto;
import com.sptg.permissions.api.dto.OrgDto;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.AccountRole;
import com.sptg.permissions.api.entity.Conf;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.enums.PermissionsEnum;
import com.sptg.permissions.api.feigns.AccountFeign;
import com.sptg.permissions.api.feigns.OrgFeign;
import com.sptg.permissions.biz.service.AccountRoleServiceInterface;
import com.sptg.permissions.biz.service.AccountServiceInterface;
import com.sptg.permissions.biz.service.ConfServiceInterface;
import com.sptg.permissions.biz.service.OrgServiceInterface;
import com.sptg.permissions.biz.stream.AccountDisableProduceInterface;
import com.sptg.third.api.entity.qinlin.QLinUser;
import com.sptg.third.api.feigns.qinlin.QLinFeign;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.stream.Collectors;

/**
 * title: AccountController
 * package: com.sptg.permissions.biz.controller
 * description: 账号-控制器
 */
@RestController
@RequiredArgsConstructor
public class AccountController implements AccountFeign {

    private final AccountServiceInterface accountServiceInterface;
    private final OrgServiceInterface orgServiceInterface;
    private final AccountDisableProduceInterface accountDisableProduceInterface;
    private final OrgFeign orgFeign;
    private final QLinFeign qLinFeign;
    private final ConfServiceInterface confServiceInterface;
    private final DeviceFeign deviceFeign;
    private final AccountRoleServiceInterface accountRoleServiceInterface;

    @Override
    @PostMapping(value = "/account/pagingQuery")
    public ResultBean<Page> pagingQuery(@RequestBody PageBean<Account, AccountDto> pageBean) {
        Page<Account> page = this.accountServiceInterface.pagingQuery(pageBean);
        return new ResultBean<>(ResultEnum.SUCCESS, page);
    }

    @Override
    @PostMapping(value = "/account/add")
    public ResultBean<Account> addEntity(@RequestBody AccountDto dto) {
        //  校验机构是否存在
        Organization organization = this.orgServiceInterface.selectById(dto.getOrgId());
        Assert.notNull(organization, "机构Id不存在");
        //  校验登陆名
        Account account = this.accountServiceInterface.selectByLoginName(dto.getLoginName());
        if (null != account) {
            return new ResultBean<>(PermissionsEnum.LOGIN_NAME_IS_EXIST);
        }
        //  账号归属机构设置
        this.accountOrganizationSetUp(dto, organization);
        ResultBean<Account> resultBean = this.accountServiceInterface.addEntity(dto);
        //检查是否有亲邻设备，有则添加用户到亲邻设备上，不然无法在后台远程开门
        DeviceVO deviceVO = new DeviceVO();
        deviceVO.setOrgPosition(dto.getOrgPosition());
        List<Device> deviceList = this.deviceFeign.getListByOrgPosition(deviceVO);
        if (deviceList != null && deviceList.size() > 0) {
            //将后台账号下发到亲邻设备，作为一个用户
            Conf conf = this.confServiceInterface.selectEntityByToken(ConfTokenName.FILE_SERVER_HOST);
            String host = conf.getConfValue();
            String userPortraitUri = dto.getUserPortraitUri();
            QLinUser qLinUser = new QLinUser();
            Date date = new Date();
            Calendar cd = Calendar.getInstance();
            cd.setTime(date);
            cd.add(Calendar.YEAR, 1);
            Date time = cd.getTime();
            String strDateFormat = "yyyy-MM-dd HH:mm:ss";
            SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
            String expires = sdf.format(time);
            qLinUser.setUserId(UserFlagConstant.ADMIN_USER_NUMBER_FLAG + dto.getId());
            qLinUser.setExpires(expires);
            qLinUser.setFaceUrl(host + userPortraitUri);
            List<String> deviceIds = deviceList.stream().map(Device::getSerialNumber).collect(Collectors.toList());
            qLinUser.setDeviceIds(String.join(",", deviceIds));
            System.out.println(JSONUtil.toJsonStr(qLinUser));
            this.qLinFeign.addUser(qLinUser);
        }
        return resultBean;
    }

    @Override
    @PostMapping(value = "/account/update")
    public ResultBean<Boolean> updateEnitiy(@RequestBody AccountDto dto) {
        //  获取修改前的账号信息
        Account dbAccount = this.accountServiceInterface.selectById(dto.getId());
        Assert.notNull(dbAccount, "账号Id不存在");
        //  判断是否修改了登录名
        if (!dbAccount.getLoginName().equals(dto.getLoginName())) {
            Account account = this.accountServiceInterface.selectByLoginName(dto.getLoginName());
            if (null != account) {
                return new ResultBean<>(PermissionsEnum.LOGIN_NAME_IS_EXIST);
            }
        }
        //  判断是否修改了归属机构
        if (null != dto.getOrgId() && !dbAccount.getOrgId().equals(dto.getOrgId())) {
            //  获取新的机构信息
            Organization organization = this.orgServiceInterface.selectById(dto.getOrgId());
            Assert.notNull(organization, "机构Id不存在");
            //  账号归属机构设置
            this.accountOrganizationSetUp(dto, organization);
            //  判断是否禁用账号
            if (!organization.getIsEnable().equals(OperationConstant.ONE)) {
                Message<Long> build = MessageBuilder.withPayload(dto.getId()).build();
                this.accountDisableProduceInterface.output().send(build);
            }
        }
        return this.accountServiceInterface.updateEntity(dto);
    }

    @Override
    @PostMapping(value = "/account/updateIsEnable")
    public ResultBean<Boolean> updateIsEnable(@RequestBody AccountDto dto) {
        //  获取修改前的账号信息
        Account dbAccount = this.accountServiceInterface.selectById(dto.getId());
        Assert.notNull(dbAccount, "账号不存在");
        //  权限校验
        Account onLineUser = dto.getOnLineUser();
        if (!dbAccount.getOrgPosition().startsWith(onLineUser.getOrgPosition())) {
            return new ResultBean<>(ResultEnum.FORBIDDEN);
        }
        //  设置账号状态
        dbAccount.setIsEnable(dto.getIsEnable());
        List<Account> accountList = new ArrayList<>(1);
        accountList.add(dbAccount);
        //  保存账号信息
        if (this.accountServiceInterface.updateBatch(accountList)) {
            //  判断是否禁用账号
            if (!dbAccount.getIsEnable().equals(OperationConstant.ONE)) {
                //  通知队列将账号强制下线
                Message<Long> build = MessageBuilder.withPayload(dto.getId()).build();
                this.accountDisableProduceInterface.output().send(build);
            }
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @PostMapping(value = "/account/delete")
    public ResultBean<Boolean> deleteEntity(@RequestBody AccountDto dto) {
        return this.accountServiceInterface.deleteEntity(dto);
    }

    @Override
    @PostMapping(value = "/account/deleteAccountList")
    public ResultBean<Boolean> deleteAccountList(@RequestBody AccountDto dto) {
        return this.accountServiceInterface.deleteAccountList(dto);
    }

    /**
     * 功能描述: 账号归属机构设置
     *
     * @param dto          账号信息
     * @param organization 机构信息
     */
    private void accountOrganizationSetUp(AccountDto dto, Organization organization) {
        //  根机构Id，机构名称，机构存储位置
        Account onLineUser = dto.getOnLineUser();
        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
        Organization selectOrg = this.orgFeign.getOrgById(dto.getOrgId());
        if (userOrg.getOrgType() == OperationConstant.THREE) {
            //物业
            //给物业创建账号
            dto.setEstatePosition(selectOrg.getPosition());
        } else {
            //机构

            //给机构创建账号
            if (selectOrg.getOrgType() == OperationConstant.THREE) {
                //给物业创建账号
                dto.setOrgPosition(userOrg.getPosition());
                dto.setEstatePosition(selectOrg.getPosition());
            } else {
                //给机构创建账号
                dto.setOrgPosition(selectOrg.getPosition());
            }
        }
        dto.setRootOrgId(organization.getRootOrgId());
        dto.setOrgName(organization.getName());
//        dto.setOrgPosition(organization.getPosition());
        //  是否可用
        dto.setIsEnable(organization.getIsEnable());
        //  账号状态
        dto.setStatus(organization.getStatus());
    }

    @Override
    @GetMapping(value = "/account/get/{id}")
    public Account getById(@PathVariable(value = "id") Long id) {
        return this.accountServiceInterface.selectById(id);
    }

    @Override
    @GetMapping(value = "/account/selectCountByPosition")
    public ResultBean<Integer> selectCountByPosition(@RequestParam(value = "orgPosition") String orgPosition) {
        return this.accountServiceInterface.selectCountByPosition(orgPosition);
    }

    @Override
    @PostMapping(value = "/account/updateIsWeChatLogin")
    public ResultBean<Boolean> updateIsWeChatLogin(@RequestBody AccountDto dto) {
        //  获取修改前的账号信息
        Account dbAccount = this.accountServiceInterface.selectById(dto.getId());
        Assert.notNull(dbAccount, "账号不存在");
        //  权限校验
        Account onLineUser = dto.getOnLineUser();
        if (!dbAccount.getOrgPosition().startsWith(onLineUser.getOrgPosition())) {
            return new ResultBean<>(ResultEnum.FORBIDDEN);
        }
        //  设置账号状态
        dbAccount.setIsWeChatLogin(dto.getIsWeChatLogin());
        List<Account> accountList = new ArrayList<>(1);
        accountList.add(dbAccount);
        //  保存账号信息
        if (this.accountServiceInterface.updateBatch(accountList)) {
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @PostMapping(value = "/account/untiedWeChat")
    public ResultBean<Boolean> untiedWeChat(@RequestBody AccountDto dto) {
        //  获取修改前的账号信息
        Account dbAccount = this.accountServiceInterface.selectById(dto.getId());
        dto.setLoginName(dbAccount.getLoginName());
        //  权限校验
        Account onLineUser = dto.getOnLineUser();
        if (!dbAccount.getOrgPosition().startsWith(onLineUser.getOrgPosition())) {
            return new ResultBean<>(ResultEnum.FORBIDDEN);
        }
        return this.accountServiceInterface.untiedWeChat(dto);
    }

    @Override
    public ResultBean<Boolean> updateById(@RequestBody Account account) {
        boolean result = this.accountServiceInterface.updateById(account);
        return new ResultBean<>(ResultEnum.SUCCESS, result);
    }

    @Override
    @GetMapping(value = "/account/getByOld/{oldId}")
    public Account getByOldId(@PathVariable(value = "oldId") String oldId) {
        Wrapper<Account> wrapper = new EntityWrapper<>();
        wrapper.eq("old_id", oldId);
        return this.accountServiceInterface.selectOne(wrapper);
    }

    @Override
    @GetMapping(value = "/account/getByOrgId/{orgId}")
    public Account getByOrgId(@PathVariable(value = "orgId") String orgId) {
        Wrapper<Account> wrapper = new EntityWrapper<>();
        wrapper.eq("l_org_id", orgId);
        return this.accountServiceInterface.selectOne(wrapper);
    }

    @Override
    @Transactional
    @GetMapping(value = "/account/addEntityByResidential")
    public Boolean addEntityByResidential(Account account) {
        account.setLoginPwd(DigestUtils.sha256Hex(account.getLoginPwd()));
        boolean insert = this.accountServiceInterface.insert(account);
        if(insert){
            //设置小区账号角色
            AccountRoleDto accountRole = new AccountRoleDto();
            accountRole.setAccountId(account.getId());
            accountRole.setRoleId(3L);
            accountRole.setCreateAccountId(1L);
            accountRole.setCreateDate(new Date());
            Account onlineUser = new Account();
            onlineUser.setId(1L);
            accountRole.setOnLineUser(onlineUser);
            this.accountRoleServiceInterface.bindUser(accountRole);
        }
        return insert;
    }

    @Override
    @PostMapping(value = "/account/page")
    public Page<Account> page(@RequestBody PageBean<Account, AccountDto> pageBean) {
        return this.accountServiceInterface.page(pageBean);
    }

    @Override
    @PostMapping(value = "/account/resetPassword")
    public ResultBean<String> resetPassword(@RequestBody AccountDto dto) {
        Account dbAccount = this.accountServiceInterface.selectById(dto.getId());
        Assert.notNull(dbAccount, "账号Id不存在");
        //  判断是否修改了登录名
        return this.accountServiceInterface.resetPassword(dbAccount);
    }

    @Override
    @PostMapping(value = "/account/modifyPassword")
    public ResultBean<Boolean> modifyPassword(@RequestBody Account account) {
        return this.accountServiceInterface.modifyPassword(account);
    }

    @Override
    @GetMapping(value = "/account/getByUserMobile")
    public Account getByUserMobile(@RequestParam(value = "userMobile") String userMobile) {
        Account account = this.accountServiceInterface.getByUserMobile(userMobile);
        return account;
    }

    public Boolean addEntityByAgency(Account account) {
        account.setLoginPwd(DigestUtils.sha256Hex(account.getLoginPwd()));
        boolean insert = this.accountServiceInterface.insert(account);
        if(insert){
            //设置社区账号角色
            AccountRoleDto accountRole = new AccountRoleDto();
            accountRole.setAccountId(account.getId());
            accountRole.setRoleId(10015L);
            accountRole.setCreateAccountId(1L);
            accountRole.setCreateDate(new Date());
            Account onlineUser = new Account();
            onlineUser.setId(1L);
            accountRole.setOnLineUser(onlineUser);
            this.accountRoleServiceInterface.bindUser(accountRole);
        }
        return insert;
    }

    @PostMapping(value = "/account/addAccoutByOrg")
    public void addAccoutByOrg() {
        OrgDto orgDto = new OrgDto();
        orgDto.setPosition("0/1/");
        List<Organization> organizations = this.orgFeign.selectListByCondition(orgDto);
        Account onlineUser = new Account();
        onlineUser.setId(1L);
        for (int i = 1; i < organizations.size(); i++) {
            Account account = new Account();
            account.setIsEnable(1);
            account.setLoginPwd("123456");
            account.setStatus(0);
            account.setUserPortraitUri("group1/M00/00/01/iwlnq1-2gWOAQZzsAAEaGqu-xVw734.jpg");
            account.setOrgId(organizations.get(i).getId());
            account.setRootOrgId(1L);
            account.setUserName(organizations.get(i).getName());
            account.setLoginName(organizations.get(i).getName());
            account.setOrgPosition(organizations.get(i).getPosition());
            if(organizations.get(i).getName().contains("社区")){//社区机构绑定社区角色
                this.addEntityByAgency(account);
            }else {
                this.addEntityByResidential(account);
            }



        }
    }
}
