package com.lanyuanxiaoyao.leopard.server.controller;

import com.lanyuanxiaoyao.leopard.core.entity.Stock;
import com.lanyuanxiaoyao.leopard.core.entity.Task;
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
import com.lanyuanxiaoyao.leopard.core.service.TaskService;
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Trigger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 下拉菜单枚举类型
 *
 * @author lanyuanxiaoyao
 * @version 20250826
 */
@Slf4j
@RestController
@RequestMapping("constants")
public class CommonOptionsController {
  public static final String COLOR_PRIMARY = "bg-primary";
  public static final String COLOR_SUCCESS = "bg-success";
  public static final String COLOR_WARNING = "bg-yellow-800";
  public static final String COLOR_ERROR = "bg-danger";
  private static final List<String> COLORS = List.of(
    "bg-black",
    "bg-primary",
    "bg-secondary",
    "bg-success",
    "bg-info",
    "bg-warning",
    "bg-danger",
    "bg-dark",
    "bg-gray-500",
    "bg-gray-600",
    "bg-gray-700",
    "bg-gray-800",
    "bg-gray-900",
    "bg-red-500",
    "bg-red-600",
    "bg-red-700",
    "bg-red-800",
    "bg-red-900",
    "bg-yellow-500",
    "bg-yellow-600",
    "bg-yellow-700",
    "bg-yellow-800",
    "bg-yellow-900",
    "bg-green-500",
    "bg-green-600",
    "bg-green-700",
    "bg-green-800",
    "bg-green-900",
    "bg-blue-500",
    "bg-blue-600",
    "bg-blue-700",
    "bg-blue-800",
    "bg-blue-900",
    "bg-cyan-500",
    "bg-cyan-600",
    "bg-cyan-700",
    "bg-cyan-800",
    "bg-cyan-900",
    "bg-indigo-500",
    "bg-indigo-600",
    "bg-indigo-700",
    "bg-indigo-800",
    "bg-indigo-900",
    "bg-purple-500",
    "bg-purple-600",
    "bg-purple-700",
    "bg-purple-800",
    "bg-purple-900",
    "bg-pink-500",
    "bg-pink-600",
    "bg-pink-700",
    "bg-pink-800",
    "bg-pink-900"
  );

  private final StockRepository stockRepository;
  private final TaskService taskService;

  public CommonOptionsController(StockRepository stockRepository, TaskService taskService) {
    this.stockRepository = stockRepository;
    this.taskService = taskService;
  }

  @GetMapping("/options/{name}")
  public GlobalResponse<List<Option>> options(@PathVariable("name") String name) {
    return switch (name) {
      case "stock_market" -> GlobalResponse.responseSuccess(
        Arrays.stream(Stock.Market.values())
          .map(market -> new Option(market.getChineseName(), market.name()))
          .sorted(Comparator.comparing(Option::label))
          .toList()
      );
      case "stock_industry" -> GlobalResponse.responseSuccess(
        stockRepository.findDistinctIndustries()
          .stream()
          .map(industry -> new Option(industry, industry))
          .sorted(Comparator.comparing(Option::label))
          .toList()
      );
      case "task_template_id" -> GlobalResponse.responseSuccess(
        taskService.getTemplates()
          .stream()
          .map(template -> new Option(template.name(), template.id()))
          .sorted(Comparator.comparing(Option::label))
          .toList()
      );
      default -> GlobalResponse.responseSuccess(List.of());
    };
  }

  @GetMapping("/mappings/{name}/{field}")
  public GlobalResponse<Map<String, String>> mappings(@PathVariable("name") String name, @PathVariable("field") String field) {
    return switch (name) {
      case "stock_market" -> GlobalResponse.responseSuccess(buildMapping(
        Arrays.stream(Stock.Market.values())
          .map(market -> new Mapping(market.name(), market.getChineseName()))
          .toList(),
        field
      ));
      case "task_status" -> GlobalResponse.responseSuccess(buildMapping(
        List.of(
          new Mapping(Task.Status.RUNNING.name(), Task.Status.RUNNING.getChineseName(), COLOR_PRIMARY),
          new Mapping(Task.Status.SUCCESS.name(), Task.Status.SUCCESS.getChineseName(), COLOR_SUCCESS),
          new Mapping(Task.Status.FAILURE.name(), Task.Status.FAILURE.getChineseName(), COLOR_ERROR),
          new Mapping(Task.Status.CANCELED.name(), Task.Status.CANCELED.getChineseName(), COLOR_WARNING)
        ),
        field
      ));
      case "trigger_status" -> GlobalResponse.responseSuccess(buildMapping(
        List.of(
          new Mapping(Trigger.TriggerState.NONE.name(), "无"),
          new Mapping(Trigger.TriggerState.NORMAL.name(), "正常", COLOR_PRIMARY),
          new Mapping(Trigger.TriggerState.PAUSED.name(), "暂停", COLOR_WARNING),
          new Mapping(Trigger.TriggerState.COMPLETE.name(), "完成", COLOR_SUCCESS),
          new Mapping(Trigger.TriggerState.ERROR.name(), "错误", COLOR_ERROR),
          new Mapping(Trigger.TriggerState.BLOCKED.name(), "阻塞", COLOR_WARNING)
        ),
        field
      ));
      default -> GlobalResponse.responseSuccess(Map.of());
    };
  }

  private Map<String, String> buildMapping(List<Mapping> mappings, String field) {
    var map = mappings
      .stream()
      .collect(Collectors.toMap(Mapping::name, mapping -> {
        return "<span class='label %s'>%s</span>".formatted(mapping.color(), mapping.label());
      }));
    map.put("*", "<span class='label bg-gray-300'>%s</span>".formatted(field));
    return map;
  }

  public record Option(String label, Object value) {
  }

  public record Mapping(String name, String label, String color) {
    public Mapping(String name, String label) {
      this(name, label, COLORS.get(Math.abs(name.hashCode()) % COLORS.size()));
    }
  }
}
