package com.corewing.app.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corewing.app.common.base.BaseEntity;
import com.corewing.app.common.enums.CommonDeleteFlagEnum;
import com.corewing.app.common.page.PageContext;
import com.corewing.app.dto.AppModel.*;
import com.corewing.app.entity.*;
import com.corewing.app.mapper.AppModelMapper;
import com.corewing.app.service.AppModelDownloadLogService;
import com.corewing.app.service.AppModelFavoriteService;
import com.corewing.app.service.AppModelFileService;
import com.corewing.app.service.AppModelService;
import com.corewing.app.util.CommonServletUtil;
import com.corewing.app.util.IpUtil;
import com.corewing.app.util.OSSUploadUtil;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.stream.IntStream;

@Service
public class AppModelServiceImpl extends ServiceImpl<AppModelMapper, AppModel> implements AppModelService {

    @Resource
    private AppModelMapper appModelMapper;

    @Resource
    private AppModelFavoriteService modelFavoriteService;

    @Resource
    private AppModelDownloadLogService modelDownloadLogService;

    @Resource
    private AppModelFileService modelFileService;

    @Override
    public Page<AppModel> page(ModelPageRequest modelPageRequest) {
        Page<AppModel> page = PageContext.getDefaultPage(AppModel.class);
        return appModelMapper.page(page, modelPageRequest);
    }

    @Override
    public List<AppModel> list(ModelListRequest modelListRequest) {
        return appModelMapper.list(modelListRequest);
    }

    @Override
    public boolean like(ModelLikeRequest modelLikeRequest) {
        AppModel appModel = this.getById(modelLikeRequest.getModelId());
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }

        LambdaUpdateWrapper<AppModel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AppModel::getId, appModel.getId());
        updateWrapper.set(AppModel::getLikeCount, appModel.getLikeCount() + 1);
        return this.update(updateWrapper);
    }

    @Override
    public boolean favorite(ModelFavoriteRequest modelFavoriteRequest) {

        // 校验是否已经收藏了
        LambdaQueryWrapper<AppModelFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModelFavorite::getModelId, modelFavoriteRequest.getModelId());
        if(modelFavoriteService.count(queryWrapper) > 0) {
            throw new RuntimeException("已经收藏了");
        }

        AppModel appModel = this.getById(modelFavoriteRequest.getModelId());
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }

        LambdaUpdateWrapper<AppModel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AppModel::getId, appModel.getId());
        updateWrapper.set(AppModel::getFavoriteCount, appModel.getFavoriteCount() + 1);
        this.update(updateWrapper);

        AppModelFavorite modelFavorite = new AppModelFavorite();
        modelFavorite.setModelId(appModel.getId());
        modelFavorite.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));

        return modelFavoriteService.save(modelFavorite);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean download(ModelDownloadRequest modelDownloadRequest) {
        AppModel appModel = this.getById(modelDownloadRequest.getModelId());
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }

        LambdaUpdateWrapper<AppModel>  updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AppModel::getId, appModel.getId());
        updateWrapper.set(AppModel::getDownloadCount, appModel.getDownloadCount() + 1);
        this.update(updateWrapper);

        AppModelDownloadLog log = new AppModelDownloadLog();
        log.setModelId(appModel.getId());
        log.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        log.setIpAddress(IpUtil.getClientIp(CommonServletUtil.getRequest()));

        return modelDownloadLogService.save(log);
    }

    @Override
    public AppModel detail(String modelId) {
        AppModel appModel = appModelMapper.getModelById(modelId);
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }

        LambdaQueryWrapper<AppModelFile>  queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModelFile::getModelId, modelId);
        List<AppModelFile> list = modelFileService.list(queryWrapper);
        if(list != null) {
            appModel.setModelFile(list);
        }
        return appModel;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean create(ModelCreateRequest modelCreateRequest) {

        // 模型标题校验
        LambdaQueryWrapper<AppModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModel::getTitle, modelCreateRequest.getTitle());
        if(count(queryWrapper) > 0) {
            throw new RuntimeException("模型标题已存在");
        }

        AppModel appModel = BeanUtil.toBean(modelCreateRequest, AppModel.class);
        appModel.setIsPublic("0");
        appModel.setStatus("1");
        appModel.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        this.save(appModel);
        // 获取文件列表
        List<MultipartFile> files = modelCreateRequest.getFiles();
        // 上传文件
        IntStream.range(0, files.size()).forEach(index -> {
            MultipartFile item = files.get(index); // 通过索引获取文件
            try {
                // 这里可以直接使用 index 作为下标（从0开始）
                String downloadUrl = OSSUploadUtil.uploadFile(item.getInputStream(), "customModel/" + item.getOriginalFilename());
                AppModelFile modelFile = new AppModelFile();
                modelFile.setFileName(item.getOriginalFilename());
                modelFile.setFileUrl(downloadUrl);
                modelFile.setFileSize(item.getSize());
                modelFile.setFileType(item.getContentType());
                modelFile.setModelId(appModel.getId());
                modelFile.setSortCode(index);
                modelFileService.save(modelFile);

            } catch (IOException e) {
                throw new RuntimeException("创建模型失败，文件下标：" + index + "，文件名：" + item.getOriginalFilename());
            }
        });
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean audit(ModelIdRequest modelIdRequest) {
        LambdaQueryWrapper<AppModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModel::getId, modelIdRequest.getModelId());
        queryWrapper.eq(AppModel::getUserId, StpUtil.getLoginId().toString());
        AppModel appModel = this.getOne(queryWrapper);
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }

        LambdaUpdateWrapper<AppModel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AppModel::getId, appModel.getId());
        updateWrapper.set(AppModel::getStatus, "2");
        return this.update(updateWrapper);
    }

    @Override
    public List<AppModel> favoriteList(ModelFavoriteListRequest modelFavoriteListRequest) {
        return appModelMapper.favoriteList(Long.valueOf(StpUtil.getLoginId().toString()), modelFavoriteListRequest);
    }

    @Override
    public Page<AppModel> favoritePage(ModelFavoritePageRequest modelFavoritePageRequest) {
        Page<AppModel> page = PageContext.getDefaultPage(AppModel.class);
        return appModelMapper.favoritePage(page, Long.valueOf(StpUtil.getLoginId().toString()), modelFavoritePageRequest);
    }

    @Override
    public boolean delisted(ModelIdRequest modelIdRequest) {
        LambdaQueryWrapper<AppModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModel::getId, modelIdRequest.getModelId());
        queryWrapper.eq(AppModel::getUserId, StpUtil.getLoginId().toString());
        AppModel appModel = this.getOne(queryWrapper);
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }
        // 下架模型后，强制将公开状态转私有，模型状态转为下架
        LambdaUpdateWrapper<AppModel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AppModel::getId, appModel.getId());
        updateWrapper.set(AppModel::getStatus, "0");
        updateWrapper.set(AppModel::getIsPublic, "0");
        return this.update(updateWrapper);
    }

    @Override
    public List<AppModel> downloadLogList(ModelDownloadLogListRequest modelDownloadLogListRequest) {
        return appModelMapper.downloadLogList(Long.valueOf(StpUtil.getLoginId().toString()), modelDownloadLogListRequest);
    }

    @Override
    public Page<AppModel> downloadLogPage(ModelDownloadLogPageRequest modelDownloadLogPageRequest) {
        Page<AppModel> page = PageContext.getDefaultPage(AppModel.class);
        return appModelMapper.downloadLogPage(page, Long.valueOf(StpUtil.getLoginId().toString()), modelDownloadLogPageRequest);
    }

    @Override
    public boolean delete(String id) {
        LambdaQueryWrapper<AppModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppModel::getId, id);
        queryWrapper.eq(AppModel::getUserId, StpUtil.getLoginId().toString());
        AppModel appModel = this.getOne(queryWrapper);
        if(appModel == null) {
            throw new RuntimeException("该模型不存在");
        }
        return this.removeById(appModel.getId());
    }


}
