package com.cmeeting.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.util.SecurityUtil;
import com.cmeeting.exception.RobotBaseException;
import com.cmeeting.mapper.primary.UserIdMapper;
import com.cmeeting.mapper.primary.WeComUserMapper;
import com.cmeeting.mapper.primary.SysUserSyncMapper;
import com.cmeeting.pojo.MeetingInfo;
import com.cmeeting.pojo.UserId;
import com.cmeeting.pojo.WeComUser;
import com.cmeeting.service.TencentMeetingService;
import com.cmeeting.service.WeComService;
import com.cmeeting.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WeComServiceImpl extends ServiceImpl<WeComUserMapper, WeComUser>  implements WeComService {

    @Value(value = "${wechat.corp_id}")
    private String CORP_ID;
    @Value(value = "${wechat.corp_secret}")
    private String CORP_SECRET;
    private static final String TOKEN_KEY = "ZHONGJI_WECOM_KEY";

    @Resource
    private WeComUserMapper weComUserMapper;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private TencentMeetingService tencentMeetingService;
    @Autowired
    private UserIdMapper userIdMapper;
    @Resource
    private SysUserSyncMapper sysUserSyncMapper;
    @Value(value = "${permission.tenantId}")
    private String permissionTenantId;

    @Override
    public void batchInsert(List<WeComUser> users) {
        weComUserMapper.batchInsert(users);
    }

    @Override
    public void doUsers() throws Exception {
        //获取所有可见范围下的部门
        JSONArray departmentList = getDepartmentList();
        Iterator<Object> iterator = departmentList.iterator();
        List<WeComUser> users = new ArrayList<>();
        while (iterator.hasNext()){
            JSONObject department = (JSONObject) iterator.next();
            String departmentId = String.valueOf(department.get("id"));
            //获取部门下的所有人员
            JSONArray userList = getUserListByDepartment(departmentId);
            for (int i = 0; i < userList.size(); i++) {
                JSONObject userJson = (JSONObject)userList.get(i);
                System.out.println("姓名: " + userJson.get("name") +
                        ", UserID: " + userJson.get("userid"));
                // 转换为WeComUser集合
                WeComUser user = new WeComUser();
                user.setUserId(userJson.getString("userid"));
                user.setUserName(userJson.getString("name"));
                users.add(user);
            }
        }
        // 检查重名并设置标志
        markDuplicateNames(users);

        // 批量插入数据库
        batchInsert(users);
    }

    @Override
    public String getToken() {
        if(redisUtils.hasKey(TOKEN_KEY)){
            return String.valueOf(redisUtils.get(TOKEN_KEY));
        }
        //获取token
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + CORP_ID + "&corpsecret=" + CORP_SECRET;
        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 = JSONObject.parseObject(responseBody);
                accessToken = jsonResponse.getString("access_token");
                redisUtils.set(TOKEN_KEY,accessToken,Integer.valueOf(jsonResponse.getString("expires_in")) - 300);
            } else {
                throw new RuntimeException("Failed to fetch token. HTTP Code: " + response.code());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return accessToken;
    }

    @Override
    public List<WeComUser> noBindUsers() {
        List<WeComUser> noBindUsers = weComUserMapper.noBindUsers();
        return noBindUsers;
    }

    /**
     * 创建预约会议（传入 wid 作为主持人）
     */
    @Override
    public MeetingInfo createTempMeeting(String wid, String token) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/meeting/create?access_token=" + token;
        org.json.JSONObject body = new org.json.JSONObject()
                .put("admin_userid", wid) // 主持人 userid
                .put("title", "Cmeeting会议助手创建会议")
                .put("meeting_start", System.currentTimeMillis() / 1000 + 3600) // 1小时后开始
                .put("meeting_duration", 3600)
                .put("invitees", new org.json.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()) {
            org.json.JSONObject json = new org.json.JSONObject(response.body().string());
            MeetingInfo meetingInfo = new MeetingInfo();
            if (json.getInt("errcode") != 0) {
                return meetingInfo; // 或者抛出异常
            }
            meetingInfo.setMeetingId(json.getString("meetingid"));
            meetingInfo.setMeetingCode(json.getString("meeting_code"));
            return meetingInfo;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

        // 2. 构造请求体（JSON格式）
        org.json.JSONObject requestBody = new org.json.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();
            org.json.JSONObject jsonResponse = new org.json.JSONObject(responseData);

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

    }

    @Override
    public void userBind() {
        String weComToken = getToken();

        //查出没有建立关联的企微人员
        List<WeComUser> noBindUsers = noBindUsers();
        List<UserId> userIds = new ArrayList<>();
        try{
            for (WeComUser user : noBindUsers) {
                MeetingInfo meetingInfo = createTempMeeting(user.getUserId(), weComToken);
                String meetingId = meetingInfo.getMeetingId();
                String meetingCode = meetingInfo.getMeetingCode();
                if (meetingCode == null || meetingCode.isEmpty()) {
                    log.error("会议创建失败，跳过用户: " + user.getUserId());
                    continue;
                }
                // 查询会议详情，获取主持人腾讯会议userid
                String hostUserId = tencentMeetingService.getMeetingHost(meetingCode);
                cancelMeeting(meetingId, weComToken); // 尝试取消无效会议
                if (hostUserId == null || hostUserId.isEmpty()) {
                    log.error("获取主持人失败，跳过会议: " + meetingCode);
                    continue;
                }
                UserId userId = UserId.builder().userName(user.getUserName()).wid(user.getUserId()).tid(hostUserId).build();
                userIds.add(userId);
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            if(!CollectionUtils.isEmpty(userIds)){
                userIdMapper.insertUsers(userIds);
            }
        }
    }

    @Override
    public Object updateEmailPushAccess(Boolean emailPushAccess) {
        RobotSecurityUser user = SecurityUtil.getUser();
        String userId = user.getId();
        if(user == null || StringUtils.isEmpty(userId)){
            throw new RobotBaseException("登录信息过期",401);
        }
        boolean update = update(null, new LambdaUpdateWrapper<WeComUser>()
                .set(WeComUser::getEmailPushAccess, emailPushAccess)
                .eq(WeComUser::getUserId, userId));
        return update;
    }

    @Override
    public Object findEmailPushAccess() {
        RobotSecurityUser user = SecurityUtil.getUser();
        String userId = user.getId();
        if(user == null || StringUtils.isEmpty(userId)){
            throw new RobotBaseException("登录信息过期",401);
        }
        WeComUser weComUser = getOne(new LambdaQueryWrapper<WeComUser>()
                .eq(WeComUser::getUserId, userId));
        //如果咨询窗用户操作的邮件推送许可，这名用户不在企微的授权范围内
        // 可以预先保存这位企微人员的信息，同时设置一下推送许可
        if(weComUser == null){
            WeComUser newUser = WeComUser.builder()
                    .userId(userId)
                    .userName(user.getUsername())
                    .isrepeatName("0")
                    .emailPushAccess(Boolean.TRUE).build();
            save(newUser);
            return newUser.getEmailPushAccess();
        }
        return weComUser.getEmailPushAccess();
    }

    /**
     * 获取企微部门列表
     *
     * @return 包含用户列表的JsonObject
     * @throws Exception
     */
    public JSONArray getDepartmentList() throws Exception {
        String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=" + getToken();

        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");

        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            JSONObject jsonResult = JSONObject.parseObject(response.toString());
            JSONArray departmentArray = (JSONArray)jsonResult.get("department_id");
            return departmentArray;
        } else {
            throw new RuntimeException("HTTP GET请求失败，错误码: " + responseCode);
        }
    }

    /**
     * 根据企业微信部门ID获取用户列表
     *
     * @param departmentId 部门ID
     * @return 包含用户列表的JsonObject
     * @throws Exception
     */
    public JSONArray getUserListByDepartment ( String departmentId) throws Exception {
        String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=" + getToken() + "&department_id=" + departmentId;

        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");

        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            JSONObject jsonResult = JSONObject.parseObject(response.toString());
            JSONArray userList = (JSONArray)jsonResult.get("userlist");
            return userList;
        } else {
            throw new RuntimeException("HTTP GET请求失败，错误码: " + responseCode);
        }
    }

    /**
     * 标记企业微信重名用户
     */
    public static void markDuplicateNames(List<WeComUser> users) {
        // 按姓名分组，统计每个名字出现的次数
        Map<String, Long> nameCountMap = users.stream()
                .collect(Collectors.groupingBy(WeComUser::getUserName, Collectors.counting()));

        // 设置是否重名标志
        users.forEach(user -> {
            if (nameCountMap.get(user.getUserName()) > 1) {
                user.setIsrepeatName("1"); // 重名
            } else {
                user.setIsrepeatName("0"); // 不重名
            }
        });
    }
}
