package org.springblade.modules.martial.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.modules.martial.pojo.dto.MoveScheduleGroupDTO;
import org.springblade.modules.martial.pojo.dto.SaveScheduleDraftDTO;
import org.springblade.modules.martial.pojo.dto.ScheduleResultDTO;
import org.springblade.modules.martial.service.IMartialScheduleArrangeService;
import org.springblade.modules.martial.service.IMartialScheduleService;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 赛程自动编排 控制器
 *
 * @author BladeX
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/martial/schedule")
@Tag(name = "赛程编排管理", description = "赛程自动编排接口")
public class MartialScheduleArrangeController extends BladeController {

	private final IMartialScheduleArrangeService scheduleArrangeService;
	private final IMartialScheduleService scheduleService;

	/**
	 * 获取编排结果
	 */
	@GetMapping("/result")
	@Operation(summary = "获取编排结果", description = "传入赛事ID")
	public R<ScheduleResultDTO> getScheduleResult(@RequestParam Long competitionId) {
		try {
			ScheduleResultDTO result = scheduleService.getScheduleResult(competitionId);
			return R.data(result);
		} catch (Exception e) {
			log.error("获取编排结果失败, competitionId: {}", competitionId, e);
			return R.fail("获取编排结果失败: " + e.getMessage());
		}
	}

	/**
	 * 保存编排草稿
	 */
	@PostMapping("/save-draft")
	@Operation(summary = "保存编排草稿", description = "传入编排草稿数据")
	public R saveDraftSchedule(@RequestBody SaveScheduleDraftDTO dto) {
		try {
			boolean success = scheduleService.saveDraftSchedule(dto);
			return success ? R.success("草稿保存成功") : R.fail("草稿保存失败");
		} catch (Exception e) {
			log.error("保存编排草稿失败", e);
			return R.fail("保存编排草稿失败: " + e.getMessage());
		}
	}

	/**
	 * 完成编排并锁定
	 */
	@PostMapping("/save-and-lock")
	@Operation(summary = "完成编排并锁定", description = "传入赛事ID")
	public R saveAndLock(@RequestBody SaveScheduleDraftDTO dto) {
		try {
			// 获取当前登录用户
			BladeUser user = AuthUtil.getUser();
			String userId = user != null ? user.getUserName() : "system";

			boolean success = scheduleService.saveAndLockSchedule(dto.getCompetitionId());
			if (success) {
				// 调用原有的锁定逻辑
				scheduleArrangeService.saveAndLock(dto.getCompetitionId(), userId);
				return R.success("编排已完成并锁定");
			} else {
				return R.fail("编排锁定失败");
			}
		} catch (Exception e) {
			log.error("保存并锁定编排失败", e);
			return R.fail("保存并锁定编排失败: " + e.getMessage());
		}
	}

	/**
	 * 手动触发自动编排(测试用)
	 */
	@PostMapping("/auto-arrange")
	@Operation(summary = "手动触发自动编排", description = "传入赛事ID,仅用于测试")
	public R autoArrange(@RequestBody Map<String, Object> params) {
		try {
			Long competitionId = Long.valueOf(String.valueOf(params.get("competitionId")));
			scheduleArrangeService.autoArrange(competitionId);
			return R.success("自动编排完成");
		} catch (Exception e) {
			log.error("自动编排失败", e);
			return R.fail("自动编排失败: " + e.getMessage());
		}
	}

	/**
	 * 移动赛程分组
	 */
	@PostMapping("/move-group")
	@Operation(summary = "移动赛程分组", description = "将分组移动到指定场地和时间段")
	public R moveGroup(@RequestBody MoveScheduleGroupDTO dto) {
		try {
			boolean success = scheduleService.moveScheduleGroup(dto);
			return success ? R.success("分组移动成功") : R.fail("分组移动失败");
		} catch (Exception e) {
			log.error("移动分组失败", e);
			return R.fail("移动分组失败: " + e.getMessage());
		}
	}

	/**
	 * 获取调度数据
	 */
	@GetMapping("/dispatch-data")
	@Operation(summary = "获取调度数据", description = "获取指定场地和时间段的调度数据")
	public R<org.springblade.modules.martial.pojo.vo.DispatchDataVO> getDispatchData(
		@RequestParam Long competitionId,
		@RequestParam Long venueId,
		@RequestParam Integer timeSlotIndex) {
		try {
			org.springblade.modules.martial.pojo.vo.DispatchDataVO data =
				scheduleService.getDispatchData(competitionId, venueId, timeSlotIndex);
			return R.data(data);
		} catch (Exception e) {
			log.error("获取调度数据失败", e);
			return R.fail("获取调度数据失败: " + e.getMessage());
		}
	}

	/**
	 * 调整出场顺序
	 */
	@PostMapping("/adjust-order")
	@Operation(summary = "调整出场顺序", description = "调整参赛者的出场顺序")
	public R adjustOrder(@RequestBody org.springblade.modules.martial.pojo.dto.AdjustOrderDTO dto) {
		try {
			boolean success = scheduleService.adjustOrder(dto);
			return success ? R.success("顺序调整成功") : R.fail("顺序调整失败");
		} catch (Exception e) {
			log.error("调整顺序失败", e);
			return R.fail("调整顺序失败: " + e.getMessage());
		}
	}

	/**
	 * 批量保存调度
	 */
	@PostMapping("/save-dispatch")
	@Operation(summary = "批量保存调度", description = "批量保存调度调整")
	public R saveDispatch(@RequestBody org.springblade.modules.martial.pojo.dto.SaveDispatchDTO dto) {
		try {
			boolean success = scheduleService.saveDispatch(dto);
			return success ? R.success("调度保存成功") : R.fail("调度保存失败");
		} catch (Exception e) {
			log.error("保存调度失败", e);
			return R.fail("保存调度失败: " + e.getMessage());
		}
	}

}
