package com.cmeeting.controller;

import com.cmeeting.mapper.primary.TecentMeetingMapper;
import com.cmeeting.mapper.primary.UserIdMapper;
import com.cmeeting.mapper.primary.WeComUserMapper;
import com.cmeeting.pojo.TencentMeetingUser;
import com.cmeeting.pojo.UserId;
import com.cmeeting.pojo.WeComUser;
import com.tencentcloudapi.wemeet.Client;
import com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder;
import com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator;
import com.tencentcloudapi.wemeet.core.exception.ClientException;
import com.tencentcloudapi.wemeet.core.exception.ServiceException;
import com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi;
import com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsGet200Response;
import com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsGet200ResponseMeetingInfoListInner;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.json.JSONObject;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping
public class UnifiedController {
    @Resource
    private WeComUserMapper weComUserMapper;
    @Resource
    private TecentMeetingMapper tecentMeetingMapper;
    @Autowired
    private UserIdMapper userIdMapper;
    List<WeComUser> weComUsers = new ArrayList<>();
    List<TencentMeetingUser> tencentMeetingUsers = new ArrayList<>();

    // 用于存放 WeComUser 的分类结果
    List<WeComUser> weComUsersIsRepeat0 = new ArrayList<>();
    List<WeComUser> weComUsersIsRepeat1 = new ArrayList<>();

    // 用于存放 TencentMeetingUser 的分类结果
    List<TencentMeetingUser> tencentUsersIsRepeat0 = new ArrayList<>();
    List<TencentMeetingUser> tencentUsersIsRepeat1 = new ArrayList<>();

    @GetMapping("/unifiled")
    public void unifiled() {
        weComUsers = weComUserMapper.getAlluser();
        tencentMeetingUsers = tecentMeetingMapper.getAlluser();
        // 分类 WeComUser 数据
        for (WeComUser user : weComUsers) {
            if ("0".equals(user.getIsrepeatName())) {
                weComUsersIsRepeat0.add(user);
            } else if ("1".equals(user.getIsrepeatName())) {
                weComUsersIsRepeat1.add(user);
            }
        }

        // 分类 TencentMeetingUser 数据
        for (TencentMeetingUser user : tencentMeetingUsers) {
            if ("0".equals(user.getIsrepeatName())) {
                tencentUsersIsRepeat0.add(user);
            } else if ("1".equals(user.getIsrepeatName())) {
                tencentUsersIsRepeat1.add(user);
            }
        }

        List<UserId> userIds = mergeUserLists(weComUsersIsRepeat0, tencentUsersIsRepeat0);

        userIdMapper.insertUsers(userIds);
    }

    @GetMapping("/insertTid")
    public void insertTid(String corpid, String corpsecret) {
        List<UserId> users = userIdMapper.getUsers();
        List<UserId> usersWithNullTid = new ArrayList<>();
        for (UserId user : users) {
            if (user.getTid() == null) {  // 同样的，根据 Tid 的实际类型调整判断条件
                usersWithNullTid.add(user);
            }
        }
        for (UserId user : usersWithNullTid) {
            //获取企业微信token
            String weComToken = getWeComToken(corpid,corpsecret);
            try {
                // 3.1 创建会议（传入用户的 wid）
                Map<String, String> meetingCodeAndMeetingid = createMeeting(user.getWid(), weComToken);
                String meetingId = meetingCodeAndMeetingid.get("meetingid");
                String meetingCode = meetingCodeAndMeetingid.get("meeting_code");
                if (meetingCode == null || meetingCode.isEmpty()) {
                    System.err.println("会议创建失败，跳过用户: " + user.getWid());
                    continue;
                }
                // 3.2 查询会议详情，获取主持人腾讯会议 userid（假设是 host_userid）
                String hostUserId = getMeetingHost(meetingCode);
                if (hostUserId == null || hostUserId.isEmpty()) {
                    System.err.println("获取主持人失败，跳过会议: " + meetingCode);
                    cancelMeeting(meetingId, weComToken); // 尝试取消无效会议
                    continue;
                }

                // 3.3 更新用户的 Tid 字段
                user.setTid(hostUserId);
                userIdMapper.updateUser(user);

                // 3.4 取消预约会议（根据需求决定是否取消）
                cancelMeeting(meetingId, weComToken);

                System.out.println("处理完成: user=" + user.getWid() + ", tid=" + hostUserId);
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("处理用户失败: " + user.getWid());
            }
        }
        //发送请求创建预约会议，获得会议号
        // createMeeting(userid);
        //通过会议号调用腾讯会议查询会议接口获取到主持人腾讯会议userid
        //将获取到的腾讯会议userid插入到该用户的Tid字段
        //取消预约会议
    }

//    @GetMapping("/sameNameInsertTid")
//    public void sameNameInsertTid(String corpid, String corpsecret) throws IOException {
//        String weComToken = getWeComToken(corpid,corpsecret);
//        List<WeComUser> sameNameUsers = weComUserMapper.getSameName();
//        List<UserId> userIds = new ArrayList<>();
//        for (WeComUser user : sameNameUsers) {
//            Map<String, String> meetingCodeAndMeetingid = createMeeting(user.getUserId(), weComToken);
//            String meetingId = meetingCodeAndMeetingid.get("meetingid");
//            String meetingCode = meetingCodeAndMeetingid.get("meeting_code");
//            if (meetingCode == null || meetingCode.isEmpty()) {
//                System.err.println("会议创建失败，跳过用户: " + user.getUserId());
//                continue;
//            }
//            // 3.2 查询会议详情，获取主持人腾讯会议 userid（假设是 host_userid）
//            String hostUserId = getMeetingHost(meetingCode);
//            if (hostUserId == null || hostUserId.isEmpty()) {
//                System.err.println("获取主持人失败，跳过会议: " + meetingCode);
//                cancelMeeting(meetingId, weComToken); // 尝试取消无效会议
//                continue;
//            }
//            UserId userId = new UserId(user.getUserName(), user.getUserId(), hostUserId);
//            userIds.add(userId);
//        }
//        userIdMapper.insertUsers(userIds);
//    }

    /**
     * 通过企业微信接口取消预约会议
     *
     * @param meetingId
     */
    private void cancelMeeting(String meetingId, String weComToken) {
        // 1. 构造请求URL
        String url = "https://qyapi.weixin.qq.com/cgi-bin/meeting/cancel?access_token=" + weComToken;

        // 2. 构造请求体（JSON格式）
        JSONObject requestBody = new JSONObject();
        requestBody.put("meetingid", meetingId);

        // 3. 发送POST请求
        OkHttpClient client = new OkHttpClient();
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json"),
                requestBody.toString()
        );
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            // 4. 解析响应
            String responseData = response.body().string();
            JSONObject jsonResponse = new JSONObject(responseData);

            if (jsonResponse.getInt("errcode") == 0) {
                System.out.println("会议取消成功: " + meetingId);
            } else {
                System.err.println("会议取消失败: " + responseData);
            }
        } catch (IOException e) {
            System.err.println("取消会议请求异常: " + e.getMessage());
        }

    }

    /**
     * 通过meetingId获取到会议主持人对应的腾讯会议userid
     *
     * @param meetingCode
     * @return
     */
    private String getMeetingHost(String meetingCode) {
        /**
         * 腾讯会议参数
         */
        Client client = new Client.Builder()
                .withAppId("211153201").withSdkId("28370276340")
                .withSecret("BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6", "3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO")
                .build();

        // 2.构造请求参数
        MeetingsApi.ApiV1MeetingsGetRequest request =
                new MeetingsApi.ApiV1MeetingsGetRequest.Builder()
                        //.operatorId("")
                        // .operatorIdType("")
                        .userid("woaJARCQAAJU1EsO73Ww5rn8YHMW6iYA")//管理员id
                        .instanceid("1")
                        .meetingCode(meetingCode)
                        //  .pos("")
                        //  .cursory("")
                        //  .isShowAllSubMeetings("")
                        .build();
        // 3.构造 JWT 鉴权器
        // 随机数
        BigInteger nonce = BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()));

        // 当前时间戳
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
        AuthenticatorBuilder<JWTAuthenticator> authenticatorBuilder =
                new JWTAuthenticator.Builder().nonce(nonce).timestamp(timestamp);
        try {
            MeetingsApi.ApiV1MeetingsGetResponse response =
                    client.meetings().v1MeetingsGet(request, authenticatorBuilder);
            // response from `v1MeetingsGet`: V1MeetingsGet200Response
            System.out.printf("Response from `MeetingsApi.v1MeetingsGet`: \nheader: %s\n%s\n",
                    response.getHeader(), response.getData());
            // 提取主持人 userid
            // 5. 处理响应数据
            if (response == null || response.getData() == null) {
                throw new RuntimeException("API响应数据为空");
            }
            // 6. 使用更安全的方式解析响应
            V1MeetingsGet200Response responseData = response.getData();
            if (responseData.getMeetingInfoList() == null || responseData.getMeetingInfoList().isEmpty()) {
                throw new RuntimeException("未找到会议信息");
            }
            V1MeetingsGet200ResponseMeetingInfoListInner meetingInfo = responseData.getMeetingInfoList().get(0);
            if (meetingInfo.getCurrentHosts() == null || meetingInfo.getCurrentHosts().isEmpty()) {
                throw new RuntimeException("会议没有主持人");
            }
            String hostUserId = meetingInfo.getCurrentHosts().get(0).getUserid();
            if (hostUserId == null || hostUserId.isEmpty()) {
                throw new RuntimeException("主持人userid为空");
            }
            System.out.println("成功获取主持人userid: {}" + hostUserId);
            return hostUserId;
        } catch (ClientException e) {
            System.out.printf("Error when calling `MeetingsApi.v1MeetingsGet`: %s\n", e);
            throw new RuntimeException(e);
        } catch (ServiceException e) {
            System.out.printf("Error when calling `MeetingsApi.v1MeetingsGet`: %s\n", e);
            System.out.printf("Full HTTP response: %s\n", new String(e.getApiResp().getRawBody()));
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取企业微信token
     *
     * @return
     */
    @GetMapping("/getWeComToken")
    public String getWeComToken(String corpid, String corpsecret) {
        //获取token
//        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww1fd8778458e9f1e8&corpsecret=uFRq9Xi8-dVY90LydXYBhjc91JnnfkPUR6lHDdeJ_fo";
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret;
        String accessToken = "";
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String responseBody = response.body().string();
                JSONObject jsonResponse = new JSONObject(responseBody);
                accessToken = jsonResponse.getString("access_token");
            } else {
                throw new RuntimeException("Failed to fetch token. HTTP Code: " + response.code());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return accessToken;
    }

    // 创建预约会议（传入 wid 作为主持人）
    private static Map<String, String> createMeeting(String wid, String weComToken) throws IOException {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/meeting/create?access_token=" + weComToken;
        JSONObject body = new JSONObject()
                .put("admin_userid", wid) // 主持人 userid
                .put("title", "自动创建会议")
                .put("meeting_start", System.currentTimeMillis() / 1000 + 3600) // 1小时后开始
                .put("meeting_duration", 3600)
                .put("invitees", new JSONObject()  // 添加 invitees 字段
                        .put("userid", new String[]{wid}) // 将 wid 作为参会人
                );

        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MediaType.parse("application/json"), body.toString()))
                .build();

        try (Response response = new OkHttpClient().newCall(request).execute()) {
            JSONObject json = new JSONObject(response.body().string());
            if (json.getInt("errcode") != 0) {
                return null; // 或者抛出异常
            }
            Map<String, String> result = new HashMap<>();
            result.put("meetingid", json.getString("meetingid"));
            result.put("meeting_code", json.getString("meeting_code"));
            return result;
        }
    }
    public List<UserId> mergeUserLists(List<WeComUser> weComUsersIsRepeat0, List<TencentMeetingUser> tencentUsersIsRepeat0) {
        List<UserId> userIds = new ArrayList<>();
        // 1. 首先构建姓名到TencentMeetingUser的映射（提高查找效率）
        Map<String, TencentMeetingUser> tencentUserMap = tencentUsersIsRepeat0.stream()
                .collect(Collectors.toMap(
                        TencentMeetingUser::getUserName,
                        user -> user,
                        (existing, replacement) -> existing)); // 如果有重名，保留第一个

        // 2. 遍历WeCom用户列表
        for (WeComUser weComUser : weComUsersIsRepeat0) {
            UserId userId = new UserId();
            userId.setUserName(weComUser.getUserName());
            userId.setWid(weComUser.getUserId()); // 始终设置WeCom userid
            // 检查是否存在同名Tencent用户
            TencentMeetingUser tencentUser = tencentUserMap.get(weComUser.getUserName());
            if (tencentUser != null) {
                userId.setTid(tencentUser.getUserId()); // 设置Tencent userid
            } else {
                userId.setTid(null); // 可以省略，默认就是null
            }
            userIds.add(userId);
        }
        // 3. 添加只存在于Tencent的用户（如果需要）
        // 这里根据需求决定是否需要这部分
        return userIds;
    }
}
