package com.aps.controller.common;

import com.aps.common.util.R;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.common.FieldInfo;
import com.aps.entity.common.Paged;
import com.aps.entity.common.SqlOrder;
import com.aps.entity.common.SqlOrderResult;
import com.aps.service.common.ChromosomeDataService;
import com.aps.service.plan.PlanResultService;
import com.aps.service.plan.SceneService;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.aps.common.util.R.ok;

@RestController
@RequestMapping("/queryChromosome")
@Tag(name = "甘特图数据查询", description = "甘特图数据查询")
public class ChromosomeDataController {

    @Autowired
    private ChromosomeDataService chromosomeDataService;
    @Autowired
    private SceneService sceneService;
    @Autowired
    private PlanResultService planResultService;

    private ObjectMapper objectMapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    /**
     * 通用接口，根据实体名称查询Chromosome中的数据，支持分页和条件过滤
     * 示例:
     * - 文件实体: POST /queryChromosome/order/page
     *   Body: { "sceneId": "SCENE001", "pageIndex": 1, "pageSize": 10, "conditions": [...] }
     * - 数据库实体: POST /queryChromosome/user/page
     *   Body: { "pageIndex": 1, "pageSize": 10, "conditions": [...] }
     *
     * @param entityName 实体名称 (如: order, entry, machine, user, department等)
     * @param paged 分页和条件对象
     * @return 分页数据
     */
    @PostMapping("/{entityName}/page")
    public R<Map<String, Object>> queryChromosomeDataWithConditions(
            @PathVariable String entityName,
            @RequestBody Paged paged) {

            // 获取sceneId（文件实体需要，数据库实体可选）
            String sceneId = paged.getCondition("sceneId") != null ?
                    paged.getCondition("sceneId").getFieldValue() : null;

            // 文件实体必须要有sceneId
            if (isFileEntity(entityName) && (sceneId == null || sceneId.isEmpty())) {
               return ok(emptyPageResult(paged));
            }

            Map<String, Object> result = chromosomeDataService.queryChromosomeDataWithConditions(
                    sceneId, entityName, paged);
            return ok(result);

    }

    /**
     * 通用接口，根据实体名称查询Chromosome中的列表数据，支持条件过滤
     * 示例:
     * - 文件实体: POST /queryChromosome/order/list
     *   Body: { "sceneId": "SCENE001", "conditions": [...] }
     * - 数据库实体: POST /queryChromosome/user/list
     *   Body: { "conditions": [...] }
     *
     * @param entityName 实体名称 (如: order, entry, machine, user, department等)
     * @param paged 条件对象
     * @return 列表数据
     */
    @PostMapping("/{entityName}/list")
    public R<List<Object>> queryChromosomeDataList(
            @PathVariable String entityName,
            @RequestBody Paged paged) {

        // 获取sceneId（文件实体需要，数据库实体可选）
        String sceneId = paged.getCondition("sceneId") != null ?
                paged.getCondition("sceneId").getFieldValue() : null;

        // 文件实体必须要有sceneId
        if (isFileEntity(entityName) && (sceneId == null || sceneId.isEmpty())) {
            return ok(Collections.emptyList());
        }

        // 直接调用服务层的list查询方法
        List<Object> result = chromosomeDataService.queryChromosomeDataList(sceneId, entityName, paged);

        if (result == null) {
            return ok(Collections.emptyList());
        }

        return ok(result);

    }

    /**
     * 通用接口，根据实体名称和ID查询Chromosome中的单个数据
     * 示例:
     * - 文件实体: GET /queryChromosome/order/get?sceneId=xxx&id=123
     * - 数据库实体: GET /queryChromosome/user/get?id=123
     *
     * @param sceneId 场景ID (文件实体必需，数据库实体可选)
     * @param entityName 实体名称
     * @param id 数据ID
     * @return 单个数据对象
     */
    @GetMapping("/{entityName}/get")
    public R<Object> queryChromosomeDataById(
            @RequestParam(required = false) String sceneId,
            @PathVariable String entityName,
            @RequestParam String id) {

            // 参数校验
            if (id == null || id.isEmpty()) {
                return R.ok(null);
            }

            // 文件实体必须要有sceneId
            if (isFileEntity(entityName) && (sceneId == null || sceneId.isEmpty())) {
                return R.ok(null);
            }

            Object result = chromosomeDataService.queryChromosomeDataById(sceneId, entityName, id);
            return ok(result);

    }

    /**
     * 通用接口，根据实体名称更新Chromosome中的数据
     * 支持文件实体（通过sceneId）和数据库实体的更新
     * 示例:
     * - 文件实体: PUT /queryChromosome/order/update?sceneId=xxx
     *   Body: { "id": 123, "fieldName": "newValue", ... }
     * - 数据库实体: PUT /queryChromosome/user/update
     *   Body: { "id": 123, "fieldName": "newValue", ... }
     *
     * @param sceneId 场景ID (文件实体必需，数据库实体可选)
     * @param entityName 实体名称
     * @param data 要更新的数据 (必须包含id字段)
     * @return 更新结果
     */
    @PostMapping("/{entityName}/update")
    @Operation(summary = "更新实体数据", description = "根据实体名称和ID更新数据，支持文件实体和数据库实体")
    public R<String> updateChromosomeData(
            @Parameter(description = "场景ID (文件实体必需，数据库实体可选)", required = false)
            @RequestParam(required = false) String sceneId,
            @Parameter(description = "taskID (文件实体必需，数据库实体可选)", required = false)
            @RequestParam(required = false) String taskId,
            @Parameter(description = "实体名称", required = true)
            @PathVariable String entityName,
            @Parameter(description = "要更新的数据 (必须包含id字段)", required = true)
            @RequestBody Map<String, Object> data) {

        // 参数校验
        if (data == null || data.isEmpty()) {
            throw new RuntimeException("更新数据不能为空");
        }
        if (data.get("id") == null) {
            throw new RuntimeException("更新数据必须包含id字段");
        }

        // 文件实体必须要有sceneId
        if (isFileEntity(entityName) && (sceneId == null || sceneId.isEmpty())) {
            throw new RuntimeException("文件实体更新时sceneId不能为空");
        }

        if (entityName.equalsIgnoreCase("machine")) {
            return chromosomeDataService.updateMachineOption(sceneId, taskId, data);
        }

        boolean success = chromosomeDataService.updateChromosomeData(sceneId, entityName, data);
        return ok("更新成功");

    }
    
    /**
     * 获取实体的字段信息
     * 示例:
     * - 文件实体: GET /queryChromosome/order/info?sceneId=xxx
     * - 数据库实体: GET /queryChromosome/user/info
     *

     * @param entityName 实体名称 (如: order, entry, machine, user, department等)
     * @return 字段信息列表
     */
    @GetMapping("/{entityName}/info")
    @Operation(summary = "获取实体字段信息", description = "根据实体名称获取字段名称、类型等信息，支持文件实体和数据库实体")
    public R<List<FieldInfo>> getEntityInfo(
            @Parameter(description = "实体名称", required = true)
            @PathVariable String entityName) {
        List<FieldInfo> fieldInfos = chromosomeDataService.getEntityInfo(entityName);
        return ok(fieldInfos);
    }

    /**
     * 判断是否为文件实体
     */
    private boolean isFileEntity(String entityName) {
        // 这里列出所有文件实体的名称
        String[] fileEntities = {"order", "entry", "machine", "globaloperationinfo", "groupresult", "prodprocessexec", "machineoption",
                "task"};
        for (String fileEntity : fileEntities) {
            if (fileEntity.equalsIgnoreCase(entityName)) {
                return true;
            }
        }
        return false;
    }

    private Map<String, Object> emptyPageResult(Paged paged) {
        Map<String, Object> result = new java.util.HashMap<>();
        result.put("records", Collections.emptyList());
        result.put("totalCount", 0);
        result.put("pageIndex", paged != null && paged.getPageIndex() != null ? Math.max(1, paged.getPageIndex()) : 1);
        result.put("size", paged != null && paged.getPageSize() != null ? paged.getPageSize() : 10);
        return result;
    }

    /**
     * 批量查询接口（report）
     * 支持在一个请求中查询多个实体
     * 示例:
     * POST /queryChromosome/report
     * Body: [
     *   {
     *     "type": "page",
     *     "name": "订单列表",
     *     "table": "order",
     *     "data": { 
     *       "pageIndex": 1, 
     *       "pageSize": 10,
     *       "conditions": [
     *         { "fieldName": "sceneId", "fieldValue": "SCENE001", "conditionalType": "EQUAL" }
     *       ]
     *     }
     *   }
     * ]
     *
     * @param sqlOrders SqlOrder列表
     * @return 查询结果Map
     */
    @PostMapping("/report")
    @Operation(summary = "批量查询接口", description = "支持在一个请求中查询多个实体，type支持 page/list/get")
    public R<Map<String, Object>> executeSqlOrderReport(
            @Parameter(description = "SqlOrder列表", required = true)
            @RequestBody List<SqlOrder> sqlOrders) {
        
        Map<String, Object> results = chromosomeDataService.executeSqlOrderReport(sqlOrders);
        return ok(results);
    }

    /**
     * 批量修改接口（commit）
     * 支持在一个请求中修改多个实体
     * 示例:
     * POST /queryChromosome/commit
     * Body: [
     *   {
     *     "type": "update",
     *     "name": "更新订单",
     *     "table": "order",
     *     "data": { 
     *       "id": 1, 
     *       "name": "新订单名称",
     *       "conditions": [
     *         { "fieldName": "sceneId", "fieldValue": "SCENE001", "conditionalType": "EQUAL" }
     *       ]
     *     }
     *   }
     * ]
     *
     * @param sqlOrders SqlOrder列表
     * @return 执行结果Map
     */
    @PostMapping("/commit")
    @Operation(summary = "批量修改接口", description = "支持在一个请求中修改多个实体，type支持 update/delete/insert")
    public R<Map<String, Object>> executeSqlOrderCommit(
            @Parameter(description = "SqlOrder列表", required = true)
            @RequestBody List<SqlOrder> sqlOrders) {
        
        Map<String, Object> results = chromosomeDataService.executeSqlOrderCommit(sqlOrders);
        return ok(results);
    }
}
