package com.cmeeting.util;

import cn.hutool.core.collection.CollUtil;
import com.cmeeting.pojo.MeetingInfo;
import com.cmeeting.util.SignatureUtil;
import com.cmeeting.vo.CorpRecordsVO;
import com.google.gson.*;
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.*;
import com.tencentcloudapi.wemeet.service.records.api.RecordsApi;
import com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response;
import com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;

/**
 * 腾讯会议API工具类
 */
@Slf4j
@Component
public class TencentMeetingApiUtil {
    private static String tencentAppId;
    @Value("${tencent.appId}")
    private String tmpAppId;
    private static String tencentSdkId;
    @Value("${tencent.sdkId}")
    private String tmpSdkId;
    private static String tencentSecretId;
    @Value("${tencent.secretId}")
    private String tmpSecretId;
    private static String tencentSecretKey;
    @Value("${tencent.secretKey}")
    private String tmpSecretKey;
    private static String tencentAdminUserId;
    @Value("${tencent.admin.userId}")
    private String tmpAdminUserId;


    private static Client client;

    @PostConstruct
    public void init() {
        tencentAppId = tmpAppId;
        tencentSdkId = tmpSdkId;
        tencentSecretId = tmpSecretId;
        tencentSecretKey = tmpSecretKey;
        tencentAdminUserId = tmpAdminUserId;
        client = getClient();
    }

    private Client getClient() {
        if (client == null) {
            synchronized (TencentMeetingApiUtil.class) {
                if (client == null) {
                    client = new Client.Builder()
                            .withAppId(tencentAppId)
                            .withSdkId(tencentSdkId)
                            .withSecret(tencentSecretId, tencentSecretKey)
                            .build();
                }
            }
        }
        return client;
    }

    /**
     * 查询会议开始结束时间
     * Api: /v1/meetings/{meeting_id}
     *
     * @param meetingId 腾讯会议id
     * @return
     */
    public static MeetingInfo getStartAndEndTimeByMeetingId(String meetingId) {
        log.info("查询会议开始结束时间,meetingId: {}", meetingId);
        MeetingInfo info = new MeetingInfo();
        AuthenticatorBuilder<JWTAuthenticator> participantsAuthenticatorBuilder =
                new JWTAuthenticator.Builder()
                        .nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt())))
                        .timestamp(String.valueOf(System.currentTimeMillis() / 1000L));

        MeetingsApi.ApiV1MeetingsMeetingIdGetRequest request = new MeetingsApi.ApiV1MeetingsMeetingIdGetRequest
                .Builder(meetingId).operatorId(tencentAdminUserId).operatorIdType("1").instanceid("2").build();
        MeetingsApi.ApiV1MeetingsMeetingIdGetResponse response = null;
        try {
            response = client.meetings().v1MeetingsMeetingIdGet(request, participantsAuthenticatorBuilder);
            V1MeetingsMeetingIdGet200Response data = response.getData();
            List<V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner> meetingInfoList = data.getMeetingInfoList();
            for (V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner meetingInfoListInner : meetingInfoList) {
                if (meetingInfoListInner.getMeetingId().equals(meetingId)) {
                    info.setMeetingId(meetingId);
                    info.setStartTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(meetingInfoListInner.getStartTime()) * 1000), ZoneId.systemDefault()));
                    info.setEndTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(meetingInfoListInner.getEndTime()) * 1000), ZoneId.systemDefault()));
                }
            }
            return info;
        } catch (ClientException | ServiceException e) {
            log.error("query meet start and end time error! message: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 查询用户已结束会议列表
     *
     * @param userId      用户id        必填
     * @param meetingCode 会议码         非必填
     * @param startTime   会议开始时间  非必填
     * @param endTime     会议结束时间  非必填
     * @return 已结束会议列表
     * @throws ServiceException
     * @throws ClientException
     */
    public static V1HistoryMeetingsUseridGet200Response ApiV1HistoryMeetingsUseridGetRequest(String userId, String meetingCode, String startTime, String endTime) {
        log.info("查询用户已结束会议列表, userId: {}, meetingCode: {}", userId, meetingCode);
        MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest historyMeetingRequest =
                new MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest.Builder(userId)
                        .pageSize("20")
                        .page("1")
                        .meetingCode(meetingCode)
                        .startTime(startTime)
                        .endTime(endTime)
                        .build();
        MeetingsApi.ApiV1HistoryMeetingsUseridGetResponse historyMeetingResponse = null;
        try {
            historyMeetingResponse = client.meetings().v1HistoryMeetingsUseridGet(historyMeetingRequest, new JWTAuthenticator.Builder()
                    .nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()))).timestamp(String.valueOf(System.currentTimeMillis() / 1000L)));
            return historyMeetingResponse.getData();
        } catch (ClientException | ServiceException e) {
            log.error("ApiV1HistoryMeetingsUseridGetRequest error: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 根据会议id查询会议详情
     *
     * @param meetingId
     * @return
     */
    public static V1MeetingsMeetingIdGet200Response ApiV1MeetingsMeetingIdGetRequest(String meetingId) {
        log.info("根据会议id查询会议详情, meetingId: {}", meetingId);
        MeetingsApi.ApiV1MeetingsMeetingIdGetRequest meetingRequest =
                new MeetingsApi.ApiV1MeetingsMeetingIdGetRequest.Builder(meetingId)
                        .operatorId(tencentAdminUserId)
                        .operatorIdType("1")
                        .instanceid("0")
                        .build();
        MeetingsApi.ApiV1MeetingsMeetingIdGetResponse meetingResponse = null;
        try {
            meetingResponse = client.meetings().v1MeetingsMeetingIdGet(meetingRequest, new JWTAuthenticator.Builder()
                    .nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt())))
                    .timestamp(String.valueOf(System.currentTimeMillis() / 1000L)));
            return meetingResponse.getData();
        } catch (ClientException | ServiceException e) {
            log.error("ApiV1MeetingsMeetingIdGetRequest error: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 获取参会成员明细
     *
     * @param meetingId    会议id
     * @param subMeetingId 子会议id
     * @return
     */
    public static V1MeetingsMeetingIdParticipantsGet200Response ApiV1MeetingsMeetingIdParticipantsGetRequest(String meetingId, String subMeetingId) {
        log.info("获取参会成员明细, meetingId: {}, subMeetingId: {}", meetingId, subMeetingId);
        MeetingsApi.ApiV1MeetingsMeetingIdParticipantsGetRequest participantsRequest =
                new MeetingsApi.ApiV1MeetingsMeetingIdParticipantsGetRequest
                        .Builder(meetingId).subMeetingId(subMeetingId).operatorId(tencentAdminUserId).operatorIdType("1").build();
        AuthenticatorBuilder<JWTAuthenticator> participantsAuthenticatorBuilder =
                new JWTAuthenticator.Builder()
                        .nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt())))
                        .timestamp(String.valueOf(System.currentTimeMillis() / 1000L));
        MeetingsApi.ApiV1MeetingsMeetingIdParticipantsGetResponse participantsResponse;
        try {
            participantsResponse = client.meetings().v1MeetingsMeetingIdParticipantsGet(participantsRequest, participantsAuthenticatorBuilder);
            return participantsResponse.getData();
        } catch (ClientException | ServiceException e) {
            log.error("ApiV1MeetingsMeetingIdParticipantsGetRequest error: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 获取转录文件内容
     *
     * @param recordFileId 转录文件id
     * @return
     */
    public static String ApiV1AddressesRecordFileIdGetRequest(String recordFileId) {
        log.info("获取转录文件内容, recordFileId: {}", recordFileId);
        //查询录制转写详情
        RecordsApi.ApiV1AddressesRecordFileIdGetRequest addressRequest =
                new RecordsApi.ApiV1AddressesRecordFileIdGetRequest.Builder(recordFileId)
                        .operatorId(tencentAdminUserId)
                        .operatorIdType("1")
                        .build();
        RecordsApi.ApiV1AddressesRecordFileIdGetResponse addressResponse;
        try {
            addressResponse = client.records().v1AddressesRecordFileIdGet(addressRequest,
                    new JWTAuthenticator.Builder().nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt())))
                            .timestamp(String.valueOf(System.currentTimeMillis() / 1000L)));
        } catch (ClientException | ServiceException e) {
            throw new RuntimeException(e);
        }
        // 处理响应
        if (addressResponse != null && addressResponse.getData() != null) {
            log.info("Successfully got address for record file {}", recordFileId);
            V1AddressesRecordFileIdGet200Response addressData = addressResponse.getData();
            // 获取AI会议转录文件
            List<V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner> transcripts =
                    addressData.getAiMeetingTranscripts();
            if (transcripts != null && !transcripts.isEmpty()) {
                log.info("Found {} AI meeting transcripts for record file {}", transcripts.size(), recordFileId);
                // 处理每个转录文件
                for (V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner transcript : transcripts) {
                    String fileType = transcript.getFileType();
                    String downloadUrl = transcript.getDownloadAddress();
                    if ("txt".equalsIgnoreCase(fileType)) {
                        log.info("AI Transcript - Type: {}, URL: {}", fileType, downloadUrl);
                        // 1. 下载文件
                        byte[] fileData = downloadFile(downloadUrl);
                        // 2. 将二进制文件转换为文本
                        String recordTextContent = new String(fileData);
                        if (StringUtils.isNotEmpty(recordTextContent.replaceAll("\\n", "").trim())) {
                            return "\n\n" + recordTextContent;
                        }
                    }
                }
            } else {
                log.info("No AI meeting transcripts found for record file {}", recordFileId);
            }
        } else {
            log.warn("Empty response for record file: {}", recordFileId);
        }
        return "";
    }

    /**
     * 根据url下载文件
     *
     * @param url
     * @return
     */
    private static byte[] downloadFile(String url) {
        // 实现文件下载逻辑
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try {
            Response response = client.newCall(request).execute();
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().bytes();
        } catch (Exception e) {
            throw new RuntimeException("下载文件失败", e);
        }
    }


}
