package com.bcxin.wps.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.wps.solution.weboffice.provider.v3.exception.FileNotExist;
import cn.wps.solution.weboffice.provider.v3.exception.InvalidToken;
import cn.wps.solution.weboffice.provider.v3.exception.UserNotExist;
import cn.wps.solution.weboffice.provider.v3.model.DownloadInfo;
import cn.wps.solution.weboffice.provider.v3.model.FileInfo;
import cn.wps.solution.weboffice.provider.v3.model.UserPermission;
import cn.wps.solution.weboffice.provider.v3.service.PreviewService;
import com.bcxin.wps.entity.File;
import com.bcxin.wps.repository.FileRepository;
import com.bcxin.wps.entity.User;
import com.bcxin.wps.repository.UserRepository;
import com.bcxin.wps.util.WpsRequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Comparator;
import java.util.Optional;

@Service
public class PreviewServiceImpl implements PreviewService {
    @Autowired
    private FileRepository fileRepository;

    @Autowired
    private UserRepository userRepository;

    @Value("${weboffice.provider.host:http://localhost:8080}")
    private String host;

    @Override
    public FileInfo fetchFileInfo(String fileId) {
        return fetchFile(fileId).toFileInfo();
    }


    // TODO liangzuobin optional is better
    File fetchFile(String fileId) {
        Optional<File> fileOptional = fileRepository.findByIdId(fileId).stream()
                .sorted(Comparator.comparing(File::getVersion).reversed()).findFirst();
        if (!fileOptional.isPresent()) {
            throw new FileNotExist();
        }

        return fileOptional.get();
    }

    @Override
    public DownloadInfo fetchDownloadInfo(String fileId) {
        return Optional.ofNullable(fileId)
                .map(fileRepository::findByIdId)
                .map(Collection::stream)
                .flatMap(s -> s.max(Comparator.comparingLong(f -> f.getVersion())))
                .map(f -> DownloadInfo.builder()
                        .url(String.format("%s/console/download/%s/%d", host, f.getId(), f.getVersion()))
                        .build())
                .orElseThrow(FileNotExist::new);
    }

    User fetchUserByToken() {
        // PAY ATTENTION token been considered as user.id here
        return Optional.of(WpsRequestUtils.getCurrentRequest())
                .map(WpsRequestUtils::getWebOfficeToken)
                .map(Long::parseLong)
                .flatMap(uid -> userRepository.findById(uid))
                .orElseThrow(InvalidToken::new);
    }

    @Override
    public UserPermission fetchUserPermission(String fileId) {
        File file = fetchFile(fileId); // check file exists
        String permissionOption = file.getPermissionOption();
        UserPermission permission =
                JSONUtil.toBean(permissionOption, UserPermission.class);

        User user = fetchUserByToken();
        if (user == null) {
            throw new UserNotExist();
        }

        permission.setUserId(String.valueOf(user.getId()));
        return permission;
        /*
        return UserPermission.builder()
                .userId(String.valueOf(user.getId()))
                .read(true)
                .update(true)
                .rename(true)
                .download(true)
                .copy(true)
                .comment(true)
                .history(true)
                .build();

         */
    }
}
