package shop.alien.store.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.StoreVideo;
import shop.alien.mapper.StoreVideoMapper;
import shop.alien.store.service.StoreVideoService;
import shop.alien.util.ali.AliOSSUtil;
import shop.alien.util.common.RandomCreateUtil;
import shop.alien.util.common.VideoUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;

/**
 * 门店视频 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Transactional
@Service
@RequiredArgsConstructor
public class StoreVideoServiceImpl extends ServiceImpl<StoreVideoMapper, StoreVideo> implements StoreVideoService {

    private final VideoUtils videoUtils;

    private final AliOSSUtil aliOSSUtil;

    /**
     * 视频文件类型列表
     */
    private static final List<String> VIDEO_FILE_TYPES = Arrays.asList("mp4", "avi", "flv", "mkv", "rmvb", "wmv", "3gp", "mov");

    @Value("${spring.web.resources.static-locations}")
    private String uploadDir;

    /**
     * 保存视频，自动截取第一帧作为封面
     *
     * @param entity 视频实体
     * @return 是否保存成功
     */
    @Override
    public boolean save(StoreVideo entity) {
        // 参数验证
        if (entity == null) {
            log.error("StoreVideoServiceImpl.save ERROR: entity is null");
            return false;
        }

        // 如果imgUrl不为空，尝试处理视频和封面
        if (StringUtils.isNotBlank(entity.getImgUrl())) {
            try {
                // 处理视频URL，截取封面并更新imgUrl字段
                String processedImgUrl = processVideoAndCover(entity.getImgUrl());
                if (StringUtils.isNotBlank(processedImgUrl)) {
                    entity.setImgUrl(processedImgUrl);
                }
            } catch (Exception e) {
                log.error("StoreVideoServiceImpl.save 处理视频封面失败, imgUrl: {}", entity.getImgUrl(), e);
                // 如果处理失败，记录错误日志但不影响保存操作
            }
        }

        // 调用父类的save方法保存
        return super.save(entity);
    }

    /**
     * 处理视频URL，截取第一帧作为封面并生成JSON数组
     *
     * @param imgUrl 视频URL或JSON字符串
     * @return 处理后的JSON数组字符串
     */
    private String processVideoAndCover(String imgUrl) {
        log.info("StoreVideoServiceImpl.processVideoAndCover imgUrl={}", imgUrl);
        
        // 参数验证
        if (StringUtils.isBlank(imgUrl)) {
            log.warn("StoreVideoServiceImpl.processVideoAndCover imgUrl is blank");
            return imgUrl;
        }

        String videoUrl = null;

        // 判断imgUrl是否为JSON格式
        try {
            JSONArray jsonArray = JSONArray.parseArray(imgUrl);
            // 如果已经是JSON数组格式，检查是否包含video和cover
            if (jsonArray != null && !jsonArray.isEmpty()) {
                JSONObject firstItem = jsonArray.getJSONObject(0);
                if (firstItem != null && firstItem.containsKey("video")) {
                    videoUrl = firstItem.getString("video");
                    // 如果已经有cover，则直接返回
                    if (firstItem.containsKey("cover") && StringUtils.isNotBlank(firstItem.getString("cover"))) {
                        log.info("StoreVideoServiceImpl.processVideoAndCover 已有封面，无需重新生成");
                        return imgUrl;
                    }
                }
            }
        } catch (Exception e) {
            // 如果不是JSON格式，则将imgUrl视为视频URL
            log.debug("StoreVideoServiceImpl.processVideoAndCover imgUrl不是JSON格式，视为视频URL");
            videoUrl = imgUrl;
        }

        // 如果videoUrl为空，无法处理
        if (StringUtils.isBlank(videoUrl)) {
            log.warn("StoreVideoServiceImpl.processVideoAndCover videoUrl is blank");
            return imgUrl;
        }

        // 检查是否为视频URL
        if (!isVideoUrl(videoUrl)) {
            log.warn("StoreVideoServiceImpl.processVideoAndCover 不是视频URL: {}", videoUrl);
            return imgUrl;
        }

        // 下载视频并截取封面
        File tempVideoFile = null;
        File coverFile = null;
        try {
            // 从URL下载视频到临时文件
            tempVideoFile = downloadVideoFromUrl(videoUrl);
            if (tempVideoFile == null || !tempVideoFile.exists()) {
                log.error("StoreVideoServiceImpl.processVideoAndCover 下载视频失败: {}", videoUrl);
                return imgUrl;
            }

            // 截取第一帧作为封面
            String coverPath = videoUtils.getFirstFrame(tempVideoFile.getAbsolutePath());
            if (StringUtils.isBlank(coverPath)) {
                log.error("StoreVideoServiceImpl.processVideoAndCover 截取封面失败: {}", tempVideoFile.getAbsolutePath());
                return imgUrl;
            }

            coverFile = new File(coverPath);
            if (!coverFile.exists()) {
                log.error("StoreVideoServiceImpl.processVideoAndCover 封面文件不存在: {}", coverPath);
                return imgUrl;
            }

            // 上传封面到OSS
            String coverFileName = generateCoverFileName(videoUrl);
            String coverOssPath = "video/" + coverFileName + ".jpg";
            String coverUrl = aliOSSUtil.uploadFile(coverFile, coverOssPath);
            if (StringUtils.isBlank(coverUrl)) {
                log.error("StoreVideoServiceImpl.processVideoAndCover 上传封面失败: {}", coverOssPath);
                return imgUrl;
            }

            // 构建JSON数组
            JSONArray resultArray = new JSONArray();
            JSONObject videoObject = new JSONObject();
            videoObject.put("video", videoUrl);
            videoObject.put("cover", coverUrl);
            resultArray.add(videoObject);

            log.info("StoreVideoServiceImpl.processVideoAndCover 处理成功, videoUrl: {}, coverUrl: {}", videoUrl, coverUrl);
            return JSON.toJSONString(resultArray);

        } catch (Exception e) {
            log.error("StoreVideoServiceImpl.processVideoAndCover 处理异常", e);
            return imgUrl;
        } finally {
            // 清理临时文件
            if (tempVideoFile != null && tempVideoFile.exists()) {
                boolean deleted = tempVideoFile.delete();
                if (!deleted) {
                    log.warn("StoreVideoServiceImpl.processVideoAndCover 删除临时视频文件失败: {}", tempVideoFile.getAbsolutePath());
                }
            }
            if (coverFile != null && coverFile.exists()) {
                boolean deleted = coverFile.delete();
                if (!deleted) {
                    log.warn("StoreVideoServiceImpl.processVideoAndCover 删除临时封面文件失败: {}", coverFile.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 检查URL是否为视频URL
     *
     * @param url 视频URL
     * @return 是否为视频URL
     */
    private boolean isVideoUrl(String url) {
        if (StringUtils.isBlank(url)) {
            return false;
        }
        // 检查URL是否以视频文件扩展名结尾
        String lowerUrl = url.toLowerCase();
        for (String videoType : VIDEO_FILE_TYPES) {
            if (lowerUrl.endsWith("." + videoType)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 从URL下载视频到临时文件
     *
     * @param videoUrl 视频URL
     * @return 临时文件对象
     */
    private File downloadVideoFromUrl(String videoUrl) {
        log.info("StoreVideoServiceImpl.downloadVideoFromUrl videoUrl={}", videoUrl);
        
        InputStream inputStream = null;
        FileOutputStream outputStream = null;
        File tempFile = null;
        
        try {
            // 创建URL连接
            URL url = new URL(videoUrl);
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(10000); // 10秒连接超时
            connection.setReadTimeout(60000); // 60秒读取超时

            // 创建临时文件
            String tempDir = uploadDir.endsWith("/") ? uploadDir : uploadDir + "/";
            String tempFileName = "temp_video_" + System.currentTimeMillis() + "_" + RandomCreateUtil.getRandomNum(6);
            
            // 从URL中提取文件扩展名
            String fileExtension = getFileExtensionFromUrl(videoUrl);
            if (StringUtils.isNotBlank(fileExtension)) {
                tempFileName += "." + fileExtension;
            } else {
                tempFileName += ".mp4"; // 默认使用mp4扩展名
            }
            
            tempFile = new File(tempDir + tempFileName);
            
            // 确保目录存在
            File parentDir = tempFile.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                parentDir.mkdirs();
            }

            // 下载文件
            inputStream = connection.getInputStream();
            outputStream = new FileOutputStream(tempFile);
            
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();

            log.info("StoreVideoServiceImpl.downloadVideoFromUrl 下载成功, tempFile: {}", tempFile.getAbsolutePath());
            return tempFile;

        } catch (Exception e) {
            log.error("StoreVideoServiceImpl.downloadVideoFromUrl 下载失败, videoUrl: {}", videoUrl, e);
            // 如果下载失败，删除可能创建的临时文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
            return null;
        } finally {
            // 关闭流
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    log.warn("StoreVideoServiceImpl.downloadVideoFromUrl 关闭输入流失败", e);
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    log.warn("StoreVideoServiceImpl.downloadVideoFromUrl 关闭输出流失败", e);
                }
            }
        }
    }

    /**
     * 从URL中提取文件扩展名
     *
     * @param url 文件URL
     * @return 文件扩展名（不包含点）
     */
    private String getFileExtensionFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        
        // 移除URL参数
        int questionMarkIndex = url.indexOf('?');
        if (questionMarkIndex > 0) {
            url = url.substring(0, questionMarkIndex);
        }
        
        // 提取扩展名
        int lastDotIndex = url.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < url.length() - 1) {
            return url.substring(lastDotIndex + 1).toLowerCase();
        }
        
        return null;
    }

    /**
     * 生成封面文件名
     *
     * @param videoUrl 视频URL
     * @return 封面文件名（不包含扩展名）
     */
    private String generateCoverFileName(String videoUrl) {
        // 从视频URL中提取文件名（去除扩展名）
        String fileName = "cover_" + System.currentTimeMillis() + "_" + RandomCreateUtil.getRandomNum(6);
        
        try {
            // 尝试从URL中提取原始文件名
            String urlPath = new URL(videoUrl).getPath();
            int lastSlashIndex = urlPath.lastIndexOf('/');
            if (lastSlashIndex >= 0 && lastSlashIndex < urlPath.length() - 1) {
                String originalFileName = urlPath.substring(lastSlashIndex + 1);
                // 移除文件扩展名
                int lastDotIndex = originalFileName.lastIndexOf('.');
                if (lastDotIndex > 0) {
                    String nameWithoutExt = originalFileName.substring(0, lastDotIndex);
                    // 清理文件名，移除特殊字符
                    nameWithoutExt = nameWithoutExt.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "");
                    if (StringUtils.isNotBlank(nameWithoutExt)) {
                        fileName = nameWithoutExt + RandomCreateUtil.getRandomNum(6);
                    }
                }
            }
        } catch (Exception e) {
            log.debug("StoreVideoServiceImpl.generateCoverFileName 从URL提取文件名失败", e);
        }
        
        // 清理文件名，避免包含逗号等特殊字符
        fileName = fileName.replaceAll(",", "");
        
        return fileName;
    }

    /**
     * 根据门店ID获取视频列表
     *
     * @param storeId 门店id
     * @return 视频列表
     */
    @Override
    public List<StoreVideo> getByStoreId(Integer storeId) {
        LambdaQueryWrapper<StoreVideo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreVideo::getStoreId, storeId)
                .orderByAsc(StoreVideo::getImgSort);
        return this.list(lambdaQueryWrapper);
    }

    /**
     * 根据门店ID和业务ID获取视频列表
     *
     * @param storeId 门店id
     * @param businessId 业务ID
     * @return 视频列表
     */
    @Override
    public List<StoreVideo> getByStoreIdAndBusinessId(Integer storeId, Integer businessId) {
        LambdaQueryWrapper<StoreVideo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreVideo::getStoreId, storeId)
                .eq(StoreVideo::getBusinessId, businessId)
                .orderByAsc(StoreVideo::getImgSort);
        return this.list(lambdaQueryWrapper);
    }
}

