package com.testor.module.globalAlarm.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.module.globalAlarm.model.domain.TGlobalAlarm;
import com.testor.module.globalAlarm.model.dto.GlobalJee;
import com.testor.module.globalAlarm.service.TGlobalAlarmService;
import com.testor.module.train.myManagement.model.domain.TSysOrgClient;
import com.testor.module.train.myManagement.service.TSysOrgClientService;
import com.testor.module.video.util.CacheUtil;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

//@RestController
//@RequestMapping("/global")
@Service
public class ClobalJeeStudio {

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private TGlobalAlarmService tGlobalAlarmService;

    @Autowired
    private TSysOrgClientService tSysOrgClientService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${global.alarem.url}")
    private String url;

    @Value("${global.alarem.username}")
    private String username;

    @Value("${global.alarem.password}")
    private String password;

//    @Value(("${global.alarem.time}"))
//    private String time;

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucket}")
    private String bucketName;

    @Value("${apisix.minioroute.url}")
    private String apisixUrl;

    private static final String TOKEN = "token";

    private static final String JEETOKEN = "jeetoken";

    // 登录
    private static final String LOGIN_URL = "/jeeStudio/gtoa/a/zlm1/cameraSet/login";
    // 获取AI视频分析
    private static final String VIDEO_AI_ANALYNE = "/jeeStudio/gtoa/a/zlm1/cameraSet/getAIInfo";
    // 获取附件列表
    private static final String FILED_LIST = "/jeeStudio/gtoa/a/system/sysFile/getFileList";
    // 获取文件流
    private static final String FILE_STREAM = "/jeeStudio/gtoa/a/system/sysFile/fileDownload";

    /**
     * 开启定时任务获取报警信息
     */
//    @GetMapping("/alarm")
    @XxlJob("globalAlarm")
    public void getVideoAiAnalyne() {
        // 参数
        List<Map<String, String>> maps = getParams();
        for (Map<String, String> params : maps) {
            String videoAiAnalyne = url + VIDEO_AI_ANALYNE;
            ResponseEntity<Map> request = this.request(videoAiAnalyne, HttpMethod.POST, Map.class, params);
            if (ObjectHelper.isEmpty(request)) {
                continue;
            }
            List<Map> rows = (List<Map>) request.getBody().get("rows");
            List<GlobalJee> globalJees = JSONArray.parseArray(JSON.toJSONString(rows), GlobalJee.class);
            List<TGlobalAlarm> jees = new ArrayList<>();
            if (ObjectHelper.isEmpty(globalJees)) {
                continue;
            }
            for (GlobalJee globalJee : globalJees) {
                TGlobalAlarm alarm = BeanHelper.beanToBean(globalJee, TGlobalAlarm.class);
                String groupId = globalJee.getGroupId();
                String photo = "";
                List<String> list = getalarmPicture(groupId);
                if (ObjectHelper.isNotEmpty(list) && list.size() > 0) {
                    for (String s : list) {
                        photo += s + ",";
                    }
                }
                alarm.setOrgId(params.get("orgId"));
                alarm.setOrgName(params.get("orgName"));
                alarm.setDisposeStatus("0");
                alarm.setAlarmPicture(photo);
                jees.add(alarm);
            }
            tGlobalAlarmService.saveBatch(jees);
        }
    }

    /**
     * 获取报警照片
     *
     * @param groupId
     * @return
     */
    private List<String> getalarmPicture(String groupId) {
        List<String> list = new ArrayList<>();
        String file = url + FILED_LIST + "?groupId=" + groupId;
        HashMap<String, String> map = new HashMap<>();
        map.put("groupId", groupId);
        ResponseEntity<Map> request = this.request(file, HttpMethod.POST, Map.class, map);
        if (ObjectHelper.isEmpty(request)) {
            return list;
        }
        Map rows = (Map) request.getBody().get("data");
        LinkedHashMap fileListMap = (LinkedHashMap) rows.get("fileListMap");
        List<Map> maps = (List<Map>) fileListMap.get("files");
        List<GlobalJee> globalJees = JSONArray.parseArray(JSON.toJSONString(maps), GlobalJee.class);
        if (ObjectHelper.isNotEmpty(globalJees)) {
            for (GlobalJee globalJee : globalJees) {
                String filePath = getFileStream(globalJee);
                list.add(filePath);
            }
        }
        return list;
    }

    /**
     * 获取文件流存入mino并返回路径
     *
     * @param globalJee
     * @return
     */
    private String getFileStream(GlobalJee globalJee) {
        String fileStream = url + FILE_STREAM + "?fileId=" + globalJee.getId();

        Resource forObject = restTemplate.getForObject(fileStream, Resource.class);
        InputStream in = null;
        String fileName = globalJee.getId() + "-" + System.currentTimeMillis() + ".jpg";


        try {
            in = forObject.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(in, in.available(), -1)
                    .contentType("image/jpeg")
                    .build()
            );
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }

        String filePath = apisixUrl + "/" + bucketName + "/" + fileName;
        return filePath;
    }

    /**
     * 获取AI报警参数
     *
     * @return
     */
    private List<Map<String, String>> getParams() {
        List<Map<String, String>> maps = new ArrayList<>();
        List<SysOrg> list = sysOrgService.list(new QueryWrapper<SysOrg>().ne(SysOrg.STATUS, BizConstants.STATUS_DELETE)
                .eq(SysOrg.IS_DEPT, "0").orderByAsc(SysOrg.TREE_LEVEL)
        );
        if (ObjectHelper.isNotEmpty(list) && list.size() > 0) {
            for (SysOrg sysOrg : list) {
                Map<String, String> hashMap = new HashMap<>();
                TGlobalAlarm alarm = tGlobalAlarmService.getOne(new QueryWrapper<TGlobalAlarm>()
                        .eq(TGlobalAlarm.ORG_ID, sysOrg.getOrgId())
                        .orderByDesc(TGlobalAlarm.SJ_DATE)
                        .last("limit 1")
                );
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String currentTime = format.format(new Date());

                TSysOrgClient one = tSysOrgClientService.getOne(new QueryWrapper<TSysOrgClient>()
                        .eq("org_id", sysOrg.getOrgId()).eq("org_code", sysOrg.getOrgCode()));
                if (one != null) {
                    sysOrg.setOrgCode(one.getClientId());
                }
                if (ObjectHelper.isNotEmpty(alarm)) {
                    String sjDate = alarm.getSjDate();
                    Date date = null;
                    try {
                        date = format.parse(sjDate);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    date.setTime(date.getTime() + 1000);
                    String bjsj = format.format(date);
                    hashMap.put("clientId", sysOrg.getOrgCode());
                    hashMap.put("orgId", sysOrg.getOrgId());
                    hashMap.put("orgName", sysOrg.getOrgName());
//            hashMap.put("clientId","151300");
                    hashMap.put("startDate", bjsj);
                    hashMap.put("endDate", currentTime);
                    hashMap.put("pageNo", "1");
                    hashMap.put("pageSize", "10");
                } else {
                    // 从当前时间的前七天开始同步
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 7);
                    String startTime = format.format(calendar.getTime());

                    hashMap.put("clientId", sysOrg.getOrgCode());
                    hashMap.put("orgId", sysOrg.getOrgId());
                    hashMap.put("orgName", sysOrg.getOrgName());
//            hashMap.put("clientId","151300");
                    hashMap.put("startDate", startTime);
                    hashMap.put("endDate", currentTime);
                    hashMap.put("pageNo", "1");
                    hashMap.put("pageSize", "10");
                }

                maps.add(hashMap);
            }
        }

        return maps;
    }

    /**
     * 获取AI视频流信息
     *
     * @param url          请求url
     * @param httpMethod   请求方式
     * @param responseType 类型
     * @param <T>
     * @return
     */

    private <T> ResponseEntity<T> request(String url, HttpMethod httpMethod, Class<T> responseType, Map<String, String> params) {
        ResponseEntity<T> response;
        try {
            if (StringUtils.isEmpty(url)) {

                throw new IllegalArgumentException();
            }
            //设置http的header
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            String jeeToken = CacheUtil.getIfPresent(JEETOKEN);
            if (!StringUtils.isNotBlank(jeeToken)) {
                //缓存中没有登录信息，先登录获取登录信息
                this.toLogin(headers);
            }
            headers.add(TOKEN, CacheUtil.getIfPresent(JEETOKEN));
            HttpEntity<Map<String, String>> requestEntity = new HttpEntity<Map<String, String>>(params, headers);
            response = restTemplate.exchange(url, httpMethod, requestEntity, responseType);
            return response;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }


    /**
     * 登录
     *
     * @param headers
     * @throws BusinessException
     * @throws JsonProcessingException
     */
    private void toLogin(HttpHeaders headers) throws BusinessException, JsonProcessingException {
        String alaremurl = url + LOGIN_URL + "?username={username}&password={password}";
        // 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        Map<String, String> params = new HashMap<>();
        params.put("username", username);
        params.put("password", password);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity httpEntity = new HttpEntity(null, headers);        //构建请求参数
        Map map = restTemplate.postForObject(alaremurl, httpEntity, Map.class, params);
        Integer code = (Integer) map.get("code");
        String token = (String) map.get("token");
        if (code == 0) {
            CacheUtil.put(JEETOKEN, token);
        } else {
            throw new BusinessException("登录错误");
        }
    }
}
