package link.at17.mid.tushare.web.controller;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;

import link.at17.mid.tushare.data.models.UpdatePlan;
import link.at17.mid.tushare.dto.LayPageReq;
import link.at17.mid.tushare.dto.LayPageResp;
import link.at17.mid.tushare.dto.R;
import link.at17.mid.tushare.service.UpdateMethodService;
import link.at17.mid.tushare.service.UpdatePlanService;
import link.at17.mid.tushare.web.exception.RException;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/admin/manage/reviews/plans")
@Slf4j
@Validated
public class UpdatePlanController extends BaseController {

    @Autowired
    Validator validator;
    
    @Autowired
    UpdateMethodService updateMethodService;
    
    @Autowired
    UpdatePlanService updatePlanService;
    
    @GetMapping("/plan-list")
    public String planList() {
        return "admin/manage/reviews/plans/plan-list";
    }

    @GetMapping("/list")
    @ResponseBody
    public LayPageResp<?> list(LayPageReq<UpdatePlan> req) {
        return new LayPageResp<>(updatePlanService.page(req, new LambdaQueryWrapper<UpdatePlan>().orderByAsc(UpdatePlan::getId)));
    }
    
    @GetMapping("/get")
    @ResponseBody
    public R<?> get(Integer id) {
        UpdatePlan plan;
        if (id == null) {
            plan = new UpdatePlan();
            return R.ok(plan);
        }
        plan = updatePlanService.getById(id);
        return R.judge(plan != null, plan, "无法找到对应 ID 的 Plan");
    }
    
    @PostMapping("/save")
    @ResponseBody
    public R<?> save(@Validated @RequestBody UpdatePlan updatePlan) {
        updatePlan.getMethods().forEach(method -> updateMethodService.fillUpdateMethodInfo(method));
        updatePlan.setValid(true);
        return R.judge(updatePlanService.saveOrUpdate(updatePlan));
    }
    
    @PostMapping("/updateBool")
    @ResponseBody
    public R<?> updateBool(Integer id, String name, Boolean value) {
        if (!List.of("enabled", "openDayCheck").contains(name)) {
            throw RException.badRequest("非法字段名" + name);
        }
        if (value == null) {
            throw RException.badRequest("不允许空值");
        }

        TableInfo tableInfo = TableInfoHelper.getTableInfo(UpdatePlan.class);
        String idField = tableInfo.getKeyColumn();
        String dbField = tableInfo.getFieldList().stream()
                .filter(f -> f.getProperty().equals(name))
                .findFirst()
                .map(TableFieldInfo::getColumn)
                .orElse(null);
        return R.judge(updatePlanService.update(new UpdateWrapper<UpdatePlan>().eq(idField, id).set(dbField, value)));
    }
    
    @PostMapping("/manualTrigger")
    @ResponseBody
    public R<?> manualTrigger(Integer id) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
        UpdatePlan updatePlan = updatePlanService.getById(id);
        return R.judge(() -> updatePlanService.triggerTask(updatePlan));
    }

}
