package com.rj.controller;

import com.rj.service.ISoundRecordingUploadService;
import com.rj.service.impl.SoundRecordingUploadServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.v3.oas.annotations.media.Schema;

/**
 * 录音上传控制器
 * 除座席机外，本接口适用于本公司所有硬件产品
 * 
 * @author rj
 * @date 2025-01-03
 */
@RestController
@RequestMapping("/api/recording")
@Tag(name = "录音上传", description = "设备端录音文件上传接口")
@Slf4j
public class SoundRecordingUploadController {

    @Autowired
    private ISoundRecordingUploadService soundRecordingUploadService;

    /**
     * 录音上传接口
     * 设备端以http协议发送文件，Content-Type：multipart/form-data
     * 认证方式：暂定无
     * 
     * @param deviceNo 设备序列号（必填）
     * @param deviceType 设备类型（可选）
     * @param soundRecording 文件数据流（必填）
     * @param fileName 文件名称（必填）
     * @param chunkIndex 分片索引（必填），A开头表示启动/运行段，Z开头表示停止段
     * @param startTime 录音开始时间，格式：yyMMddHHmmss（必填）
     * @param endTime 录音结束时间，格式：yyMMddHHmmss（必填）
     * @param usrNo 自定义编号（可选）
     * @return 上传结果
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "录音上传", description = "设备端录音文件上传接口，支持分片上传")
    public ResponseEntity<SoundRecordingUploadResponse> uploadRecording(
            @Parameter(description = "设备序列号", required = true)
            @RequestParam("deviceNo") String deviceNo,
            @Parameter(description = "设备类型")
            @RequestParam(value = "deviceType", required = false) String deviceType,
            @Parameter(description = "录音文件数据流", required = true)
            @RequestParam("soundRecording") MultipartFile soundRecording,
            @Parameter(description = "文件名称", required = true)
            @RequestParam("fileName") String fileName,
            @Parameter(description = "分片索引，A开头表示启动/运行段，Z开头表示停止段", required = true)
            @RequestParam("chunkIndex") String chunkIndex,
            @Parameter(description = "录音开始时间，格式：yyMMddHHmmss", required = true)
            @RequestParam("startTime") String startTime,
            @Parameter(description = "录音结束时间，格式：yyMMddHHmmss", required = true)
            @RequestParam("endTime") String endTime,
            @Parameter(description = "自定义编号")
            @RequestParam(value = "usrNo", required = false) String usrNo) {
        
        log.info("收到录音上传请求 - deviceNo: {}, fileName: {}, chunkIndex: {}, startTime: {}, endTime: {}", 
                deviceNo, fileName, chunkIndex, startTime, endTime);
        
        // 记录业务层处理开始时间
        long startTimeMillis = System.currentTimeMillis();
        
        // 调用服务层处理业务逻辑
        SoundRecordingUploadServiceImpl.ResponseData serviceResponse = soundRecordingUploadService.uploadRecording(
                deviceNo, deviceType, soundRecording, fileName, chunkIndex, startTime, endTime, usrNo);
        
        // 记录业务层处理结束时间并计算耗时
        long endTimeMillis = System.currentTimeMillis();
        long elapsedTime = endTimeMillis - startTimeMillis;
        double elapsedTimeSeconds = elapsedTime / 1000.0;
        log.info("业务层处理完成 - deviceNo: {}, 耗时: {} 秒", deviceNo, String.format("%.2f", elapsedTimeSeconds));
        
        // 转换服务层返回的结果为响应对象
        SoundRecordingUploadResponse response = new SoundRecordingUploadResponse();
        response.setCode(serviceResponse.code);
        response.setStatus(serviceResponse.status);
        response.setSuccess(serviceResponse.success);
        response.setMessage(serviceResponse.message);
        response.setTimestamp(serviceResponse.timestamp);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 录音上传请求DTO（内部类）
     */
    @Schema(description = "录音上传请求参数")
    public static class SoundRecordingUploadRequest {
        private String deviceNo;
        private String deviceType;
        private MultipartFile soundRecording;
        private String fileName;
        private String chunkIndex;
        private String startTime;
        private String endTime;
        private String usrNo;
        
        // Getters and Setters
        public String getDeviceNo() { return deviceNo; }
        public void setDeviceNo(String deviceNo) { this.deviceNo = deviceNo; }
        public String getDeviceType() { return deviceType; }
        public void setDeviceType(String deviceType) { this.deviceType = deviceType; }
        public MultipartFile getSoundRecording() { return soundRecording; }
        public void setSoundRecording(MultipartFile soundRecording) { this.soundRecording = soundRecording; }
        public String getFileName() { return fileName; }
        public void setFileName(String fileName) { this.fileName = fileName; }
        public String getChunkIndex() { return chunkIndex; }
        public void setChunkIndex(String chunkIndex) { this.chunkIndex = chunkIndex; }
        public String getStartTime() { return startTime; }
        public void setStartTime(String startTime) { this.startTime = startTime; }
        public String getEndTime() { return endTime; }
        public void setEndTime(String endTime) { this.endTime = endTime; }
        public String getUsrNo() { return usrNo; }
        public void setUsrNo(String usrNo) { this.usrNo = usrNo; }
    }
    
    /**
     * 录音上传响应DTO（内部类）
     */
    @Schema(description = "录音上传响应")
    public static class SoundRecordingUploadResponse {
        @Schema(description = "状态码，200或204表示成功", example = "200")
        private Integer code;
        
        @Schema(description = "上传状态，0表示成功", example = "0")
        private Integer status;
        
        @Schema(description = "是否成功", example = "true")
        private Boolean success;
        
        @Schema(description = "消息", example = "请求成功")
        private String message;
        
        @Schema(description = "时间戳（单位：秒）", example = "1704268800")
        private Long timestamp;
        
        // Getters and Setters
        public Integer getCode() { return code; }
        public void setCode(Integer code) { this.code = code; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        public Boolean getSuccess() { return success; }
        public void setSuccess(Boolean success) { this.success = success; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public Long getTimestamp() { return timestamp; }
        public void setTimestamp(Long timestamp) { this.timestamp = timestamp; }
    }
}

