package com.dji.sample.psdk.controller;

import com.dji.sample.psdk.model.dto.SpeakerPlayDTO;
import com.dji.sample.psdk.service.IPsdkService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.mqtt.services.ServicesReplyData;
import com.dji.sdk.mqtt.services.TopicServicesResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * PSDK controller
 * 
 * @author GeoFly Team
 * @version 1.0
 * @date 2026-02-03
 */
@Slf4j
@RestController
@RequestMapping("${url.psdk.prefix}${url.psdk.version}")
public class PsdkController {

    @Autowired
    private IPsdkService psdkService;

    /**
     * Send custom data to PSDK
     */
    @PostMapping("/devices/{device_sn}/psdk/custom-data")
    public HttpResultResponse<ServicesReplyData> sendCustomData(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam(value = "psdk_index", required = false, defaultValue = "2") Integer psdkIndex,
            @RequestBody String data) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.sendCustomDataToPsdk(deviceSn, psdkIndex, data);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to send custom data: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Set PSDK widget value
     */
    @PostMapping("/devices/{device_sn}/psdk/widget")
    public HttpResultResponse<ServicesReplyData> setWidgetValue(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex,
            @RequestParam("widget_index") Integer widgetIndex,
            @RequestParam("value") Integer value) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.setWidgetValue(deviceSn, psdkIndex, widgetIndex, value);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to set widget value: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Set PSDK input box text
     */
    @PostMapping("/devices/{device_sn}/psdk/input-box")
    public HttpResultResponse<ServicesReplyData> setInputBoxText(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex,
            @RequestBody String text) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.setInputBoxText(deviceSn, psdkIndex, text);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to set input box text: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Play audio on speaker
     */
    @PostMapping("/devices/{device_sn}/speaker/audio/play")
    public HttpResultResponse<ServicesReplyData> playAudio(
            @PathVariable("device_sn") String deviceSn,
            @Valid @RequestBody SpeakerPlayDTO playDTO) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.playAudio(deviceSn, playDTO);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to play audio: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Play TTS on speaker
     */
    @PostMapping("/devices/{device_sn}/speaker/tts/play")
    public HttpResultResponse<ServicesReplyData> playTts(
            @PathVariable("device_sn") String deviceSn,
            @Valid @RequestBody SpeakerPlayDTO playDTO) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.playTts(deviceSn, playDTO);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to play TTS: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Replay on speaker
     */
    @PostMapping("/devices/{device_sn}/speaker/replay")
    public HttpResultResponse<ServicesReplyData> replay(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.replay(deviceSn, psdkIndex);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to replay: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Stop playing on speaker
     */
    @PostMapping("/devices/{device_sn}/speaker/stop")
    public HttpResultResponse<ServicesReplyData> stopPlay(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.stopPlay(deviceSn, psdkIndex);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to stop play: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Set speaker play mode
     */
    @PostMapping("/devices/{device_sn}/speaker/mode")
    public HttpResultResponse<ServicesReplyData> setPlayMode(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex,
            @RequestParam("play_mode") Integer playMode) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.setPlayMode(deviceSn, psdkIndex, playMode);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to set play mode: " + response.getData().getResult().getCode());
        }
    }

    /**
     * Set speaker volume
     */
    @PostMapping("/devices/{device_sn}/speaker/volume")
    public HttpResultResponse<ServicesReplyData> setVolume(
            @PathVariable("device_sn") String deviceSn,
            @RequestParam("psdk_index") Integer psdkIndex,
            @RequestParam("volume") Integer volume) {
        
        TopicServicesResponse<ServicesReplyData> response = 
                psdkService.setVolume(deviceSn, psdkIndex, volume);
        
        if (response.getData().getResult().isSuccess()) {
            return HttpResultResponse.success(response.getData());
        } else {
            return HttpResultResponse.error("Failed to set volume: " + response.getData().getResult().getCode());
        }
    }
}
