package rd.controller.activity;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import rd.data.dto.activity.ActivityTargetAddDto;
import rd.data.dto.activity.ActivityTargetUpdateDto;
import rd.data.db.table.ActivityTarget;
import rd.data.model.request.activity.ActivityTargetAddRequest;
import rd.data.model.request.activity.ActivityTargetUpadeRequest;
import rd.data.model.response.Response;
import rd.data.model.response.activity.ActivityTargetResponse;
import rd.data.model.response.activity.ActivityTargetWithClassNameResponse;
import rd.service.activity.ActivityTargetService;
import rd.service.course.CourseService;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/admin/activity/targets")
public class AdminActivityTargetController {
    private final ActivityTargetService activityTargetService;
    private final CourseService courseService;

    public AdminActivityTargetController(ActivityTargetService activityTargetService, CourseService courseService) {
        this.activityTargetService = activityTargetService;
        this.courseService = courseService;
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @GetMapping("/list")
    public Response<List<ActivityTargetWithClassNameResponse>> listActivityTarget(@RequestParam("act") Long activityId) {
        var activityTargetList = activityTargetService.getActivityTargetList(activityId);
        var activityTargetResponseList = activityTargetList.stream().map(activityTarget -> {
                    var activityTargetResponse = convertWithCourseName(activityTarget);
                    var courseNameList = Arrays.stream(activityTarget.getCourseList())
                            .map(courseId -> {
                                var course = courseService.getCourse(courseId);
                                return course == null ? (String.format("[已删除课程%d]", courseId)) : course.getName();
                            })
                            .toList();
                    activityTargetResponse.setCourse(courseNameList);
                    return activityTargetResponse;
                })
                .toList();

        return Response.success(activityTargetResponseList);
    }

    private ActivityTargetWithClassNameResponse convertWithCourseName(ActivityTarget activityTarget) {
        ActivityTargetWithClassNameResponse activityTargetWithClassNameResponse = new ActivityTargetWithClassNameResponse();
        activityTargetWithClassNameResponse.setId(activityTarget.getId());
        activityTargetWithClassNameResponse.setActivity(activityTarget.getActivity());
        activityTargetWithClassNameResponse.setGrade(activityTarget.getGrade());
        activityTargetWithClassNameResponse.setMajor(activityTarget.getMajor());
        activityTargetWithClassNameResponse.setCreateTime(activityTarget.getCreateTime());
        activityTargetWithClassNameResponse.setEditTime(activityTarget.getEditTime());

        return activityTargetWithClassNameResponse;
    }

    private ActivityTargetResponse convertWithCourseId(ActivityTarget activityTarget) {
        ActivityTargetResponse activityTargetWithClassNameResponse = new ActivityTargetResponse();
        activityTargetWithClassNameResponse.setId(activityTarget.getId());
        activityTargetWithClassNameResponse.setActivity(activityTarget.getActivity());
        activityTargetWithClassNameResponse.setGrade(activityTarget.getGrade());
        activityTargetWithClassNameResponse.setMajor(activityTarget.getMajor());
        activityTargetWithClassNameResponse.setCourse(Arrays.asList(activityTarget.getCourseList()));
        activityTargetWithClassNameResponse.setCreateTime(activityTarget.getCreateTime());
        activityTargetWithClassNameResponse.setEditTime(activityTarget.getEditTime());

        return activityTargetWithClassNameResponse;
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @GetMapping("/info")
    public Response<ActivityTargetResponse> getActivityTargetInfo(@RequestParam("id") Long id) {
        var activityTarget = activityTargetService.getActivityTargetInfo(id);
        return Response.success(convertWithCourseId(activityTarget));
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @PostMapping("/add")
    public Response<Object> addActivityTarget(@RequestParam("act") Long activityId,
                                              @RequestBody ActivityTargetAddRequest activityTargetAddRequest
    ) {
        activityTargetService.addActivityTargetCourse(activityId, convert(activityTargetAddRequest));
        return Response.success();
    }

    private ActivityTargetAddDto convert(ActivityTargetAddRequest request) {
        ActivityTargetAddDto activityTargetAddDto = new ActivityTargetAddDto();
        activityTargetAddDto.setGrade(request.getGrade());
        activityTargetAddDto.setMajor(request.getMajor());
        activityTargetAddDto.setCourse(request.getCourse());

        return activityTargetAddDto;
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @PostMapping("/duplicate")
    public Response<Object> duplicateActivityTarget(@RequestParam("src") Long src, @RequestParam("dst") Long dst) {
        activityTargetService.duplicateFromExistsActivity(src, dst);
        return Response.success();
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @PostMapping("/update")
    public Response<Object> updateActivityTarget(@RequestParam("id") Long id,
                                                 @RequestBody ActivityTargetUpadeRequest activityTargetUpadeRequest
    ) {
        activityTargetService.updateActivityTargetCourse(id, convert(activityTargetUpadeRequest));
        return Response.success();
    }

    private ActivityTargetUpdateDto convert(ActivityTargetUpadeRequest request) {
        ActivityTargetUpdateDto activityTargetUpdateDto = new ActivityTargetUpdateDto();
        activityTargetUpdateDto.setGrade(request.getGrade());
        activityTargetUpdateDto.setMajor(request.getMajor());
        activityTargetUpdateDto.setCourse(request.getCourse());

        return activityTargetUpdateDto;
    }

    @SaCheckLogin
    @SaCheckRole("ADMIN")
    @PostMapping("/delete")
    public Response<Object> deleteActivityTarget(@RequestParam("id") Long id) {
        activityTargetService.removeActivityTargetCourse(id);
        return Response.success();
    }
}
