package com.sino.mci.send.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sino.mci.admin.security.AuthContext;
import com.sino.mci.send.dto.SendPreviewRequest;
import com.sino.mci.send.dto.SendPreviewResponse;
import com.sino.mci.send.dto.SendRecordResponse;
import com.sino.mci.send.dto.SendRequest;
import com.sino.mci.send.dto.SendResponse;
import com.sino.mci.send.dto.SendStatisticsResponse;
import com.sino.mci.send.dto.SendTaskStatusResponse;
import com.sino.mci.send.dto.SendTestRequest;
import com.sino.mci.send.service.SendPreviewService;
import com.sino.mci.send.service.SendService;
import com.sino.mci.shared.web.ApiResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@RestController
@RequestMapping("/api/v1/send")
@RequiredArgsConstructor
public class SendController {

    private final SendService sendService;
    private final SendPreviewService sendPreviewService;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

    @PostMapping
    public ApiResponse<SendResponse> send(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @Valid @RequestBody SendRequest request) {
        return ApiResponse.ok(sendService.send(tenantCode, request));
    }

    @PostMapping("/test")
    public ApiResponse<SendResponse> testSend(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @Valid @RequestBody SendTestRequest request) {
        return ApiResponse.ok(sendService.testSend(tenantCode, request));
    }

    @PostMapping("/preview")
    public ApiResponse<SendPreviewResponse> preview(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @Valid @RequestBody SendPreviewRequest request) {
        return ApiResponse.ok(sendPreviewService.preview(tenantCode, request));
    }

    @RequestMapping(value = "/{task_id}/records", method = {RequestMethod.GET, RequestMethod.POST})
    public ApiResponse<List<SendRecordResponse>> listRecords(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @PathVariable("task_id") String taskId) {
        return ApiResponse.ok(sendService.listRecords(tenantCode, taskId));
    }

    @GetMapping("/{task_id}/status")
    public ApiResponse<SendTaskStatusResponse> getTaskStatus(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @PathVariable("task_id") String taskId) {
        return ApiResponse.ok(sendService.getTaskStatus(tenantCode, taskId));
    }

    @PostMapping("/{task_id}/cancel")
    public ApiResponse<Integer> cancelTask(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @PathVariable("task_id") String taskId) {
        return ApiResponse.ok(sendService.cancelTask(tenantCode, taskId));
    }

    @GetMapping("/records")
    public ApiResponse<IPage<SendRecordResponse>> queryRecords(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @RequestParam(required = false) String taskId,
            @RequestParam(required = false) String start,
            @RequestParam(required = false) String end,
            @RequestParam(required = false) String channelType,
            @RequestParam(required = false) Integer status,
            @RequestParam(defaultValue = "1") long page,
            @RequestParam(defaultValue = "20") long size) {
        LocalDateTime startTime = parseDateTime(start);
        LocalDateTime endTime = parseDateTime(end);
        return ApiResponse.ok(sendService.queryRecords(tenantCode, taskId, startTime, endTime,
                channelType, status, page, size));
    }

    @GetMapping("/statistics")
    public ApiResponse<SendStatisticsResponse> statistics(
            @RequestHeader("X-Tenant-Code") String tenantCode,
            @RequestParam(required = false) String start,
            @RequestParam(required = false) String end) {
        LocalDateTime startTime = parseDateTime(start);
        LocalDateTime endTime = parseDateTime(end);
        return ApiResponse.ok(sendService.getStatistics(tenantCode, startTime, endTime));
    }

    @GetMapping("/list")
    public ApiResponse<List<SendRecordResponse>> listRecentRecords() {
        return ApiResponse.ok(sendService.listRecentRecords(AuthContext.currentTenantCode()));
    }

    private LocalDateTime parseDateTime(String value) {
        if (!StringUtils.hasText(value)) {
            return null;
        }
        return LocalDateTime.parse(value, DATE_TIME_FORMATTER);
    }
}
