package com.qqchen.deploy.backend.framework.controller;

import com.qqchen.deploy.backend.framework.domain.Entity;
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import com.qqchen.deploy.backend.framework.query.BaseQuery;
import com.qqchen.deploy.backend.framework.api.Response;
import com.qqchen.deploy.backend.framework.service.IBaseService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 通用REST控制器
 */
@Validated
public abstract class BaseController<T extends Entity<ID>, D extends BaseDTO, ID extends Serializable, Q extends BaseQuery> {

    protected IBaseService<T, D, Q, ID> service;

    @PostMapping
    public Response<D> create(@Validated @RequestBody D dto) {
        return Response.success(service.create(dto));
    }

    @PutMapping("/{id}")
    public Response<D> update(@PathVariable ID id, @Validated @RequestBody D dto) {
        return Response.success(service.update(id, dto));
    }

    @DeleteMapping("/{id}")
    public Response<Void> delete(@PathVariable ID id) {
        service.delete(id);
        return Response.success();
    }

    @GetMapping("/{id}")
    public Response<D> findById(@PathVariable ID id) {
        return Response.success(service.findById(id));
    }

    @GetMapping
    public Response<List<D>> findAll() {
        return Response.success(service.findAll());
    }

    @GetMapping("/page")
    public Response<Page<D>> page(Q query) {
        return Response.success(service.page(query));
    }

    @GetMapping("/list")
    public Response<List<D>> findAll(Q query) {
        return Response.success(service.findAll(query));
    }

    @PostMapping("/batch")
    public CompletableFuture<Response<Void>> batchProcess(@RequestBody List<D> dtos) {
        return CompletableFuture.runAsync(() -> {
            service.batchProcess(dtos);
        }).thenApply(v -> Response.success());
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response, Q query) {
        List<D> data = service.findAll(query);
        exportData(response, data);
    }

    /**
     * 导出数据的具体实现
     *
     * @param response HTTP响应
     * @param data     要导出的数据
     */
    protected abstract void exportData(HttpServletResponse response, List<D> data);

}