package cn.reghao.tnb.file.app.zdisk.service;

import cn.reghao.jutil.jdk.web.db.Page;
import cn.reghao.jutil.jdk.web.db.PageList;
import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.tnb.auth.api.dto.AccountAvatar;
import cn.reghao.tnb.auth.api.iface.AccountQuery;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.file.app.zdisk.db.mapper.DiskAlbumMapper;
import cn.reghao.tnb.file.app.zdisk.db.mapper.DiskShareMapper;
import cn.reghao.tnb.file.app.zdisk.db.repository.DiskCamRepository;
import cn.reghao.tnb.file.app.zdisk.db.repository.DiskShareRepository;
import cn.reghao.tnb.file.app.zdisk.model.constant.AlbumType;
import cn.reghao.tnb.file.app.zdisk.model.dto.ShareCreate;
import cn.reghao.tnb.file.app.zdisk.model.po.CamDevice;
import cn.reghao.tnb.file.app.zdisk.model.po.DiskAlbum;
import cn.reghao.tnb.file.app.zdisk.model.po.DiskShare;
import cn.reghao.tnb.file.app.zdisk.model.po.DiskShareTo;
import cn.reghao.tnb.file.app.zdisk.model.vo.DiskShareInfo;
import cn.reghao.tnb.common.util.IdService;
import cn.reghao.tnb.user.api.iface.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2025-09-05 17:03:48
 */
@Service
public class DiskShareService {
    @DubboReference(check = false, retries = 0, timeout = 60_000)
    private AccountQuery accountQuery;
    @DubboReference(check = false, retries = 0, timeout = 60_000)
    private UserService userService;

    private int pageSize = 10;
    private final IdService idService;
    private final DiskShareMapper diskShareMapper;
    private final DiskAlbumMapper diskAlbumMapper;
    private final DiskShareRepository diskShareRepository;
    private final DiskCamRepository diskCamRepository;

    public DiskShareService(IdService idService, DiskShareMapper diskShareMapper,
                            DiskAlbumMapper diskAlbumMapper, DiskShareRepository diskShareRepository,
                            DiskCamRepository diskCamRepository) {
        this.idService = idService;
        this.diskShareMapper = diskShareMapper;
        this.diskAlbumMapper = diskAlbumMapper;
        this.diskShareRepository = diskShareRepository;
        this.diskCamRepository = diskCamRepository;
    }

    public Result createShare(ShareCreate shareCreate) {
        long loginUser = UserContext.getUserId();
        int albumType = shareCreate.getAlbumType();
        long albumId = shareCreate.getAlbumId();
        if (albumType == AlbumType.cam.getValue()) {
            CamDevice camDevice = diskCamRepository.getCamDevice(albumId, loginUser);
            if (camDevice == null) {
                return Result.fail("not owner");
            }
        } else if (albumType == AlbumType.image.getValue()) {
            DiskAlbum diskAlbum = diskAlbumMapper.findDiskAlbum(albumId);
            if (diskAlbum == null || diskAlbum.getCreateBy() != loginUser) {
                return Result.fail("not owner");
            }
        } else {
            return Result.fail("error albumType");
        }
        
        long shareId = idService.getLongId();
        DiskShare diskShare = new DiskShare(shareId, shareCreate);
        List<DiskShareTo> list = shareCreate.getShareToList().stream()
                .map(username -> {
                    long userId = accountQuery.getByUsername(username).getUserId();
                    return new DiskShareTo(shareId, userId);
                })
                .collect(Collectors.toList());

        diskShareMapper.save(diskShare);
        if (!list.isEmpty()) {
            diskShareMapper.saveDiskShareTo(list);
        }
        return Result.success();
    }

    public Result deleteShare(long shareId) {
        DiskShare diskShare = diskShareMapper.findDiskShare(shareId);
        if (diskShare == null || diskShare.getCreateBy() != UserContext.getUserId()) {
            return Result.fail("not owner");
        }

        diskShareRepository.deleteShare(shareId);
        return Result.success();
    }

    public PageList<DiskShareInfo> getShareList(int pageNumber) {
        long loginUser = UserContext.getUserId();
        Page page = new Page(pageNumber, pageSize);
        List<DiskShareInfo> list = diskShareMapper.findDiskShareByPage(page, loginUser).stream()
                .map(diskShare -> {
                    int albumType = diskShare.getAlbumType();
                    long albumId = diskShare.getAlbumId();
                    String albumName = "";
                    if (albumType == AlbumType.cam.getValue()) {
                        CamDevice camDevice = diskCamRepository.getCamDevice(albumId, loginUser);
                        if (camDevice == null) {
                            return null;
                        }
                        albumName = camDevice.getCamName();
                    } else if (albumType == AlbumType.image.getValue()) {
                        DiskAlbum diskAlbum = diskAlbumMapper.findDiskAlbum(albumId);
                        if (diskAlbum == null) {
                            return null;
                        }
                        albumName = diskAlbum.getAlbumName();
                    } else {
                        return null;
                    }

                    int num = diskShareMapper.countDiskShareTo(diskShare.getShareId());
                    return new DiskShareInfo(diskShare, albumName, num);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        int total = diskShareMapper.countDiskShare(loginUser);
        return PageList.pageList(pageNumber, pageSize, total, list);
    }

    public List<AccountAvatar> getShareToList(long shareId) {
        List<Long> userIds = diskShareMapper.findDiskShareToList(shareId);
        return userIds.stream()
                .map(userId -> accountQuery.getAccountAvatar(userId))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 获取分享给用户的合集 ID, 需要动态检测分享者与被分享者之间的关系变化
     *
     * @param
     * @return
     * @date 2025-09-06 00:09:512
     */
    public List<Long> getSharedAlbumIds(int albumType, long shareTo) {
        List<DiskShare> diskShareList = diskShareMapper.findDiskShareList(albumType, shareTo);
        return diskShareList.stream()
                .map(diskShare -> {
                    long shareId = diskShare.getShareId();
                    long createBy = diskShare.getCreateBy();
                    return userService.contactContain(createBy, shareTo) ? diskShare.getAlbumId() : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
}
