package com.imooc.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.base.BaseInfoProperties;
import com.imooc.grace.result.GraceJSONResult;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.pojo.Users;
import com.imooc.service.FansService;
import com.imooc.service.UserService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = "FansController 粉丝相关业务功能的接口")
@RequestMapping("fans")
@RestController
public class FansController extends BaseInfoProperties {

    @Autowired
    private UserService userService;
    @Autowired
    private FansService fansService;

    @PostMapping("follow")
    public GraceJSONResult follow(@RequestParam String myId,
                                  @RequestParam String vlogerId) {
        // 从redis中获取拉黑信息
        String redisKey = REDIS_USER_BLOCK + ":" + myId;
        Boolean hasKey = redis.keyIsExist(redisKey);
        if(hasKey){
            List<String> blockUserList = new ArrayList<>();
            ObjectMapper objectMapper = new ObjectMapper();
            List<String> reports = redis.lrange(redisKey, 0, -1);  // 查询用户的所有举报记录

            for (String report : reports) {
                try {
                    Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {});
                    // 处理拉黑信息
                    String queryvlogerId = (String) reportMap.get("vlogerId");
                    blockUserList.add(queryvlogerId);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(blockUserList);
            Boolean isBlock = blockUserList.contains(vlogerId);
            if(isBlock){
                return GraceJSONResult.errorCustom(ResponseStatusEnum.ON_BLOCK);
            }
        }

        // 判断两个id不能为空
        if (StringUtils.isBlank(myId) || StringUtils.isBlank(vlogerId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR);
        }

        // 判断当前用户，自己不能关注自己
        if (myId.equalsIgnoreCase(vlogerId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_RESPONSE_NO_INFO);
        }

        // 是否已经存在关系
        Boolean flow = fansService.queryDoIFollowVloger(myId,vlogerId);
        if(flow){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FANS_INFO_UPDATED_ISFAN_EXIST_ERROR);
        }

        // 判断两个id对应的用户是否存在
        Users vloger = userService.getUser(vlogerId);
        Users myInfo = userService.getUser(myId);

        // fixme: 两个用户id的数据库查询后的判断，是分开好？还是合并判断好？
        if (myInfo == null || vloger == null) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_RESPONSE_NO_INFO);
        }
//
        // 保存粉丝关系到数据库
        fansService.doFollow(myId, vlogerId);

        // 博主的粉丝+1，我的关注+1
        redis.increment(REDIS_MY_FOLLOWS_COUNTS + ":" + myId, 1);
        redis.increment(REDIS_MY_FANS_COUNTS + ":" + vlogerId, 1);

        // 我和博主的关联关系，依赖redis，不要存储数据库，避免db的性能瓶颈
        redis.set(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + myId + ":" + vlogerId, "1");
//
        return GraceJSONResult.ok();
    }

    @PostMapping("cancel")
    public GraceJSONResult cancel(@RequestParam String myId,
                                  @RequestParam String vlogerId) {
        // 判断两个id不能为空
        if (StringUtils.isBlank(myId) || StringUtils.isBlank(vlogerId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR);
        }
        // 是否已经存在关系
        Boolean flow = fansService.queryDoIFollowVloger(myId,vlogerId);
        if(!flow){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FANS_INFO_UPDATED_ISFLOW_EXIST_ERROR);
        }
        // 删除业务的执行
        fansService.doCancel(myId, vlogerId);

        // 博主的粉丝-1，我的关注-1
        redis.decrement(REDIS_MY_FOLLOWS_COUNTS + ":" + myId, 1);
        redis.decrement(REDIS_MY_FANS_COUNTS + ":" + vlogerId, 1);

        // 我和博主的关联关系，依赖redis，不要存储数据库，避免db的性能瓶颈
        redis.del(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + myId + ":" + vlogerId);

        return GraceJSONResult.ok();
    }

    @GetMapping("queryBlockVloger")
    public GraceJSONResult queryBlockVloger(@RequestParam String myId,
                                                @RequestParam String vlogerId) {
        // 从redis中获取拉黑信息
        String redisKey = REDIS_USER_BLOCK + ":" + myId;
        Boolean hasKey = redis.keyIsExist(redisKey);
        if(hasKey){
            List<String> blockUserList = new ArrayList<>();
            ObjectMapper objectMapper = new ObjectMapper();
            List<String> reports = redis.lrange(redisKey, 0, -1);  // 查询用户的所有举报记录

            for (String report : reports) {
                try {
                    Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {});
                    // 处理拉黑信息
                    String queryvlogerId = (String) reportMap.get("vlogerId");
                    blockUserList.add(queryvlogerId);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(blockUserList);
            return GraceJSONResult.ok(blockUserList.contains(vlogerId));
        }else{
            return GraceJSONResult.ok(false);
        }
    }

    @PostMapping("block")
    public GraceJSONResult block(@RequestParam String myId,
                                  @RequestParam String vlogerId) {
        // 先执行cancel
        // 判断两个id不能为空
        if (StringUtils.isBlank(myId) || StringUtils.isBlank(vlogerId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR);
        }
        // 是否已经存在关系
        Boolean flow = fansService.queryDoIFollowVloger(myId,vlogerId);
        if(flow){
            // 删除业务的执行
            fansService.doCancel(myId, vlogerId);

            // 博主的粉丝-1，我的关注-1
            redis.decrement(REDIS_MY_FOLLOWS_COUNTS + ":" + myId, 1);
            redis.decrement(REDIS_MY_FANS_COUNTS + ":" + vlogerId, 1);

            // 我和博主的关联关系，依赖redis，不要存储数据库，避免db的性能瓶颈
            redis.del(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + myId + ":" + vlogerId);
        }
        // 拉黑
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String blockTime = LocalDateTime.now().format(formatter);
        try{
            Map<String, String> blockInfo = new HashMap<>();
            blockInfo.put("vlogerId", vlogerId);
            blockInfo.put("myId", myId);
            blockInfo.put("time", blockTime);
            // 转成 JSON 字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String blockJson = objectMapper.writeValueAsString(blockInfo);
            String redisKey = REDIS_USER_BLOCK + ":" + myId ;
            log.info("写入Redis => key: {}, value: {}", redisKey, blockJson);
            redis.rpush(redisKey , blockJson);

            return GraceJSONResult.ok();
        }catch (JsonProcessingException e){
            // 打日志，或者抛出业务异常
            e.printStackTrace();
            throw new RuntimeException("JSON序列化失败: " + e.getMessage());
        }
    }

    @PostMapping("cancelBlock")
    public GraceJSONResult cancelBlock(@RequestParam String myId,
                                 @RequestParam String vlogerId) {
        // 判断两个id不能为空
        if (StringUtils.isBlank(myId) || StringUtils.isBlank(vlogerId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR);
        }
        // 解除拉黑
        String redisKey = REDIS_USER_BLOCK + ":" + myId;
        Boolean hasKey = redis.keyIsExist(redisKey);
        if(hasKey){
            List<String> blockList = redis.lrange(redisKey, 0, -1);
            ObjectMapper objectMapper = new ObjectMapper();
            if (blockList != null && !blockList.isEmpty()) {
                for (String item : blockList) {
                    try {
                        Map<String, String> itemMap = objectMapper.readValue(item, new TypeReference<Map<String, String>>() {});
                        String storedVlogerId = itemMap.get("vlogerId");

                        if (storedVlogerId != null && storedVlogerId.equals(vlogerId)) {
                            redis.lrem(redisKey, 1, item);  // 删除找到的 JSON 字符串
                            break;
                        }
                    }catch (JsonProcessingException e){
                        e.printStackTrace();
                    }
                }
            }
            return GraceJSONResult.ok();
        }else{
            return  GraceJSONResult.error();
        }
    }

    @PostMapping("blockVideo")
    public GraceJSONResult blockVideo(@RequestParam String myId,
                                      @RequestParam String vlogId,
                                      @RequestParam String reason,
                                 @RequestParam(defaultValue = "") String description) {
        // 判断两个id不能为空
        if (StringUtils.isBlank(myId) || StringUtils.isBlank(vlogId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR);
        }
        // 拉黑
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String blockTime = LocalDateTime.now().format(formatter);
        //
        try{
            Map<String, String> blockInfo = new HashMap<>();
            blockInfo.put("vlogId", vlogId);
            blockInfo.put("reporter", myId);
            blockInfo.put("time", blockTime);
            blockInfo.put("reason", reason);
            blockInfo.put("description", description);
            // 转成 JSON 字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String blockJson = objectMapper.writeValueAsString(blockInfo);

            String redisKey = REDIS_VIDEO_BLOCK + ":" + myId ;
            log.info("写入Redis => key: {}, value: {}", redisKey, blockJson);
            redis.rpush(redisKey , blockJson);

            return GraceJSONResult.ok();
        }catch (JsonProcessingException e){
            // 打日志，或者抛出业务异常
            e.printStackTrace();
            throw new RuntimeException("JSON序列化失败: " + e.getMessage());
        }
    }



    @GetMapping("queryDoIFollowVloger")
    public GraceJSONResult queryDoIFollowVloger(@RequestParam String myId,
                                                @RequestParam String vlogerId) {
        return GraceJSONResult.ok(fansService.queryDoIFollowVloger(myId, vlogerId));
    }

    @GetMapping("queryMyFollows")
    public GraceJSONResult queryMyFollows(@RequestParam String myId,
                                          @RequestParam Integer page,
                                          @RequestParam Integer pageSize) {
        return GraceJSONResult.ok(
                fansService.queryMyFollows(
                        myId,
                        page,
                        pageSize));
    }

    @GetMapping("queryMyFans")
    public GraceJSONResult queryMyFans(@RequestParam String myId,
                                          @RequestParam Integer page,
                                          @RequestParam Integer pageSize) {
        return GraceJSONResult.ok(
                fansService.queryMyFans(
                        myId,
                        page,
                        pageSize));
    }
}
