package com.guwan.backend.controller;

import cn.hutool.json.JSONObject;
import com.guwan.backend.annotation.OperationLog;
import com.guwan.backend.client.SimpleTTSClient;
import com.guwan.backend.client.VoiceServiceClient;
import com.guwan.backend.common.Result;
import com.guwan.backend.pojo.entity.BookContent;
import com.guwan.backend.mongodb.EveryReadDetailOfMongodb;
import com.guwan.backend.mongodb.EveryReadDetailOfMongodbService;
import com.guwan.backend.mongodb.User;
import com.guwan.backend.mongodb.MongodbUserService;
import com.guwan.backend.service.BookContentService;
import com.guwan.backend.util.MinioUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@RestController
@RequestMapping("/api/common")
@RequiredArgsConstructor
public class CommonController {

    private final MinioUtil minioUtil;

    private final VoiceServiceClient voiceServiceClient;
    private final SimpleTTSClient simpleTTSClient;




    private final BookContentService bookContentService;

    private final MongodbUserService mongodbUserService;

    private final EveryReadDetailOfMongodbService everyReadDetailOfMongodbService;

    @PostMapping("/uploadFile")
    public Result<String> uploadFile(String bucketName, MultipartFile file){
        return Result.success(minioUtil.getUrl(minioUtil.getFileUrl
                (bucketName, minioUtil.uploadFile(bucketName, file))));
    }

    @PostMapping("/addBookComment")
    public Result<String> addBookComment(String url) {
        log.debug(url);
        //   "http://localhost:9000/txt/8357cf6b-9637-4354-9ee6-2717141f665a.txt";
        OkHttpClient client = new OkHttpClient();

        // 创建一个请求对象
        Request request = new Request.Builder()
                .url(url)
                .build();

        // 发起同步请求
        try {
            String content = getTextUsingOkHttp(client, request);
            ArrayList<BookContent> bookContents = processContent(content);
            bookContentService.saveBatch(bookContents);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return Result.success("ok");
    }

    // 通过 OkHttpClient 发起同步请求获取文件内容
    public static String getTextUsingOkHttp(OkHttpClient client, Request request) throws IOException {
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body().string();  // 返回文件内容
            } else {
                throw new IOException("Unexpected code " + response);
            }
        }
    }

    // 处理文件内容,提取卷和节
    public static ArrayList<BookContent> processContent(String content) {
        // 正则表达式,提取卷和节
        String volumePattern = "第([一二三四五六七八九十]+)卷";  // 提取卷
        String sectionPattern = "第([一二三四五六七八九十零百]+)节:(.*)";  // 提取节及其节名

        // 提取卷
        Pattern volumeRegex = Pattern.compile(volumePattern);
        Matcher volumeMatcher = volumeRegex.matcher(content);

        // 提取节
        Pattern sectionRegex = Pattern.compile(sectionPattern);
        Matcher sectionMatcher = sectionRegex.matcher(content);

        // 列表来存储所有卷和节的内容
        List<String> volumes = new ArrayList<>();  // 存储所有卷的标题
        List<String> sections = new ArrayList<>();  // 存储所有节的标题
        List<String> sectionContents = new ArrayList<>();  // 存储每节的正文内容

        // 收集卷的信息
        while (volumeMatcher.find()) {
            String volume = "第" + volumeMatcher.group(1) + "卷";
            volumes.add(volume);
        }

        // 收集节的信息
        while (sectionMatcher.find()) {
            String sectionTitle = "第" + sectionMatcher.group(1) + "节:" + sectionMatcher.group(2).trim();  // 这里去掉节名前后空格
            sections.add(sectionTitle);

            // 获取节的正文内容
            int start = sectionMatcher.end();  // 获取节标题之后的位置
            int end = content.length();  // 默认到文件末尾

            // 查找下一个节的位置(即本节内容的结束位置)
            Matcher nextSectionMatcher = sectionRegex.matcher(content);
            if (nextSectionMatcher.find(start)) {
                end = nextSectionMatcher.start();
            }

            // 获取当前节的正文内容
            String sectionContent = content.substring(start, end).trim();
            sectionContents.add(sectionContent);
        }

        // 标记是否是第一次匹配到“第一节”
        boolean isFirstSection = true;

        ArrayList<BookContent> bookContents = new ArrayList<>();

        int sectionId = 1;

        // 输出卷和节信息
        for (int i = 0; i < volumes.size(); i++) {
            // 输出卷的标题

            // 输出该卷的每一节标题和正文内容
            for (int j = 0; j < sections.size(); j++) {

               // System.out.print(volumes.get(i));
                String section = sections.get(j);
                String sectionContent = sectionContents.get(j);

                // 输出节标题
              //  System.out.println("    " + section);

                // 输出节的正文内容
            //    System.out.println("        正文: " + sectionContent);

                // 如果是“第一节”,并且不是第一次出现,递增卷的索引
                if (section.contains("第一节") && !isFirstSection) {
                    i++;  // 不是第一次才递增
                }

                // 第一次匹配到“第一节”后,标记为false
                isFirstSection = false;


                BookContent bookContent = new BookContent();
                bookContent.setBookName("大爱仙尊");
                bookContent.setVolume(volumes.get(i));
                bookContent.setSection(section);
                bookContent.setSectionContent(sectionContent);
                bookContent.setSectionId(sectionId++);

                System.out.println("bookContent = " + bookContent);

                bookContents.add(bookContent);


            }


        }
        return bookContents;
    }


    @GetMapping("/getBookComment")
    public Result<String> getBookComment(Long id) {
        BookContent bookContent = bookContentService.getById(id);
        return Result.success(bookContent.getSectionContent());
    }


    @GetMapping("/getBookContent")
    public Result<String> getBookContent(String bookName, Long id) {
        BookContent bookContent = bookContentService.getBookContent(bookName, id);
        return Result.success(bookContent.getSectionContent());
    }




    @GetMapping("/getBookCommentByPath")
    public ResponseEntity<Map<String, Object>> getBookCommentByPath(@RequestParam("id") Long id) {
            // 从数据库中获取评论内容
            //String comments = bookContentService.getById(id).getSectionContent();

            BookContent byId = bookContentService.lambdaQuery()
                    .eq(BookContent::getBookName, "大爱仙尊")
                    .eq(BookContent::getSectionId, id).one();

            // 构造返回数据
            Map<String, Object> response = new HashMap<>();
            response.put("data", byId);

            return ResponseEntity.ok(response);

    }


    @GetMapping("/testMongodb")
    public Result testMongodb(){


        User user = new User();
        user.setId("1");
        user.setName("1");
        user.setAge(1L);
        user.setEmail("1");

        mongodbUserService.save(user);

        return Result.success();
    }


    @PostMapping("/everyRead")
    public Result everyRead(@RequestBody EveryReadDetailOfMongodb everyReadDetailOfMongodb){


        everyReadDetailOfMongodbService.save(everyReadDetailOfMongodb);


        return Result.success();
    }

    @GetMapping("/getUserOneTotalTime")
    @OperationLog(description = "统计用户某本书的读书时间")
    public Result getUserOneTotalTime(@RequestParam Long userId){


        //return Result.success();

       // everyReadDetailOfMongodbService.getUserOneTotalTime(userId);

        return Result.success(everyReadDetailOfMongodbService.getUserOneTotalTime(userId));
    }



    /**
     * model 默认值  /model/faster-whisper-small/
     */
    @PostMapping("/convertVoiceToText")
    public Result convertVoiceToText(MultipartFile file, String model) {

        if (model == null){
            model = "/model/faster-whisper-small/";
        }

        return Result.success(voiceServiceClient.voiceToText(file, model));
    }


    @PostMapping("/simpleTTS")
    public Result simpleTTS(String input, String voiceModel) {


        if (voiceModel == null) {
            voiceModel = "zh-CN-XiaoxiaoNeural";
        }

        // 使用 JSONObject 构造JSON
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("input", input);
        jsonObject.put("voice", voiceModel);

        String jsonInputString = jsonObject.toString();
        System.out.println(jsonInputString);


     //   jsonInputString = "{\"input\": \"想听个啥123\", \"voice\": \"zh-CN-XiaoxiaoNeural\", \"style\": \"\", \"rate\": 0, \"pitch\": 0}";


        String url = minioUtil.getUrl(minioUtil.getFileUrl("temp",
                minioUtil.uploadByteArray(
                        simpleTTSClient.saveAudio(jsonInputString), "mp3")));


        return Result.success(url);
    }



    @PostMapping("/testPart")
    public void testPart(@RequestPart(value = "file", required = false) MultipartFile file,
                         @RequestPart(value = "str1", required = false) String str1,
                         @RequestPart(value = "f1", required = false) String f1) {

        String s = null;
        if (file != null) {
            s = minioUtil.uploadFile("temp", file);
        }

        System.out.println("s = " + s);

        System.out.println("str1 = " + str1);

        System.out.println("f1 = " + f1);

    }


    @PostMapping("/testPartOfFloat")
    public void testPartOfFloat(@RequestPart(value = "file", required = false) MultipartFile file,
                         @RequestPart(value = "str1", required = false) String str1,
                         @RequestPart(value = "f1", required = false) Float f1) {

        String s = null;
        if (file != null) {
            s = minioUtil.uploadFile("temp", file);
        }

        System.out.println("s = " + s);

        System.out.println("str1 = " + str1);

        System.out.println("f1 = " + f1);

    }



    @PostMapping("/testParam")
    public void testParm(@RequestPart(value = "file", required = false) MultipartFile file,
                         @RequestParam(value = "str1", required = true) String str1,
                         @RequestParam(value = "f1", required = false) Float f1) {

        String s = null;
        if (file != null) {
            s = minioUtil.uploadFile("temp", file);
        }


        System.out.println("s = " + s);

        System.out.println("str1 = " + str1);

        System.out.println("f1 = " + f1);

    }


}