package cn.ibizlab.api.rest.extensions;

import cn.ibizlab.core.lite.domain.DstSystem;
import cn.ibizlab.core.lite.domain.MetaField;
import cn.ibizlab.core.lite.extensions.domain.*;
import cn.ibizlab.core.lite.extensions.model.DataModel;
import cn.ibizlab.core.lite.extensions.model.Property;
import cn.ibizlab.core.lite.extensions.service.DbEntityService;
import cn.ibizlab.core.lite.extensions.service.LiteDataService;
import cn.ibizlab.core.lite.extensions.service.LiteModelService;
import cn.ibizlab.util.client.IBZDictFeignClient;
import cn.ibizlab.util.dict.CodeItem;
import cn.ibizlab.util.dict.CodeList;
import cn.ibizlab.util.dict.Option;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Api(tags = {"接口" })
@RestController("api-litecore")
@RequestMapping("")
public class DstCoreResource {

    @Autowired
    private LiteModelService liteModelService;

    @Autowired
    private LiteDataService liteDataService;

    @Autowired
    private DbEntityService dbEntityService;

    @RequestMapping(method = RequestMethod.GET, value = "/dst/test/{modelid}/data/{key}")
    public ResponseEntity<ModelObj> getstr(@PathVariable(name="modelid",required = false) String modelid,@PathVariable(name="key",required = false) String key)
    {

        if(StringUtils.isEmpty(modelid))
            modelid="dataModelff8080816a8b510c016a8c2f18b10001";
        return ResponseEntity.ok(liteDataService.getModelObjs(modelid, null,key));
    }

    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}","/dst/datamodels/{modelid}/name/{modelname}"})
    public ResponseEntity<DataModel> getDataModel(@PathVariable(name="modelid",required = false) String modelid,
                                                  @PathVariable(name="modelname",required = false) String modelname)
    {
        return ResponseEntity.ok(liteModelService.getDataModel(modelid,modelname));
    }

    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/submodels","/dst/datamodels/{modelid}/name/{modelname}/submodels"})
    public ResponseEntity<List<Option>> getDataModelSubModels(@PathVariable(name="modelid",required = false) String modelid,
                                                              @PathVariable(name="modelname",required = false) String modelname)
    {
        List<Option> list =  new ArrayList<>();
        liteModelService.getDataModel(modelid,modelname).getSubDataModel().forEach(dataModel -> list.add(new Option().setId(dataModel.getDataModelName()).setLabel(dataModel.getFactPorperty().getEntityModel().getLogicName()+"["+dataModel.getDataModelName()+"]")));
        return ResponseEntity.ok(list);
    }

    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/propertys","/dst/datamodels/{modelid}/name/{modelname}/propertys"})
    public ResponseEntity<List<Option>> getDataModelParentProperty(@PathVariable(name="modelid",required = false) String modelid,
                                                              @PathVariable(name="modelname",required = false) String modelname)
    {
        List<Option> list =  new ArrayList<>();
        liteModelService.getDataModel(modelid,modelname).getParentProperty().forEach(property -> {
            Option option = new Option().setId(property.getPropertyName()).setLabel(property.getEntityModel().getLogicName()+"["+property.getPropertyName()+"]");
            list.add(option);
        });
        return ResponseEntity.ok(list);
    }



    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/propertys/{propertyname}/fields","/dst/datamodels/{modelid}/name/{modelname}/propertys/{propertyname}/fields"})
    public ResponseEntity<List<Option>> getDataModelParentField(@PathVariable(name="modelid",required = false) String modelid,
                                                                   @PathVariable(name="modelname",required = false) String modelname,
                                                                @PathVariable(name="propertyname",required = false) String propertyname)
    {
        List<Option> list =  new ArrayList<>();
        Property property=liteModelService.getDataModel(modelid,modelname).findObjectProperty(propertyname,"UP");
        property.getEntityModel().getFields().forEach(field -> {
            Option option = new Option().setId(property.getPropertyName()+"."+field.getColumnName()).setLabel(field.getComment()+"["+field.getColumnName()+"]");
            list.add(option);
        });
        return ResponseEntity.ok(list);
    }


    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/allpropertys"})
    public ResponseEntity<List<Option>> getDataModelParentProperty(@PathVariable(name="modelid",required = false) String modelid)
    {
        List<Option> list =  new ArrayList<>();
        liteModelService.getDataModel(modelid).getAllProperty().forEach(property -> {
            Option option = new Option().setId(property.getPropertyName()).setLabel(property.getEntityModel().getLogicName()+"["+property.getPropertyName()+"]");
            list.add(option);
        });
        return ResponseEntity.ok(list);
    }
    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/allpropertys/{propertyname}/fields"})
    public ResponseEntity<List<Option>> getDataModelField(@PathVariable(name="modelid",required = false) String modelid,
                                                                @PathVariable(name="propertyname",required = false) String propertyname,
                                                                @PathVariable(name="fieldname",required = false) String fieldname)
    {
        List<Option> list =  new ArrayList<>();
        Property property=liteModelService.getDataModel(modelid).findObjectProperty(propertyname,"ALL");
        property.getEntityModel().getFields().forEach(field -> {
            Option option = new Option().setId(property.getPropertyName()+"."+field.getColumnName()).setLabel(field.getComment()+"["+field.getColumnName()+"]");
            list.add(option);
        });
        return ResponseEntity.ok(list);
    }

    @Autowired
    private IBZDictFeignClient dictFeignClient;

    @RequestMapping(method = RequestMethod.GET, value = {"/dst/datamodels/{modelid}/{propertyname}.{fieldname}/dict"})
    public ResponseEntity<List<CodeItem>> getDataModelFieldDict(@PathVariable(name="modelid",required = false) String modelid,
                                                                @PathVariable(name="propertyname",required = false) String propertyname,
                                                                @PathVariable(name="fieldname",required = false) String fieldname)
    {
        List<CodeItem> list =  new ArrayList<>();
        Property property=liteModelService.getDataModel(modelid).findObjectProperty(propertyname,"ALL");
        if(property!=null)
        {
            MetaField field=property.getEntityModel().getField(fieldname).getField();
            if(field!=null)
            {
                String dict = field.getDict();
                if(!StringUtils.isEmpty(dict))
                {
                    CodeList codeList=dictFeignClient.getCodeList(dict);
                    if(codeList!=null)
                        list=codeList.getOptions();

                }
            }

        }

        return ResponseEntity.ok(list);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/dst/{system}/entitys")
    public ResponseEntity<List<EntityModel>> getEntityModel(@PathVariable("system") String system) {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getEntityModel(system));
    }

    @RequestMapping(method = RequestMethod.GET, value = "/dst/{system}/entitys/{entity}")
    public ResponseEntity<EntityModel> getEntityModel(@PathVariable("system") String system, @PathVariable("entity") String entity) {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getEntityModel(system,entity));
    }

    @RequestMapping(method = RequestMethod.GET, value = "/dst/{system}/entitys/{entity}/fields")
    public ResponseEntity<List<FieldModel>> getEntityModelFields(@PathVariable("system") String system, @PathVariable("entity") String entity) {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getEntityModel(system,entity).getFields());
    }

    @RequestMapping(method = RequestMethod.GET, value = "/dst/{system}/entitys/{entity}/references")
    public ResponseEntity<List<RelationshipModel>> getEntityModelReferences(@PathVariable("system") String system, @PathVariable("entity") String entity) {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getEntityModel(system,entity).getReferences());
    }

    @RequestMapping(method = RequestMethod.GET, value = "/dst/{system}/entitys/{entity}/nesteds")
    public ResponseEntity<List<RelationshipModel>> getEntityModelNesteds(@PathVariable("system") String system, @PathVariable("entity") String entity) {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getEntityModel(system,entity).getNesteds());
    }



    @RequestMapping(method = RequestMethod.GET, value = "/dst/sysapps")
    public ResponseEntity<List<DstSystem>> getSysApps() {
        return ResponseEntity.status(HttpStatus.OK).body(liteModelService.getSysApp());
    }


}
