package com.jakubu9333.grammarManager.api;

import com.fasterxml.jackson.annotation.JsonView;
import com.jakubu9333.grammarManager.model.Grammar;
import com.jakubu9333.grammarManager.model.RuleModel;

import com.jakubu9333.grammarManager.model.View;
import com.jakubu9333.grammarManager.service.GrammarService;
import com.jakubu9333.grammarManager.service.RuleService;
import org.javatuples.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

/**
 * @author Jakub Uhlarik
 */

@RestController
@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(path = "api/rules")
public class RuleController {

    private final RuleService ruleService;
    private final GrammarService grammarService;

    @Autowired
    public RuleController(RuleService ruleService, GrammarService grammarService) {
        this.ruleService = ruleService;
        this.grammarService = grammarService;
    }


    @JsonView(View.GrammarWithoutRules.class)
    @GetMapping("")
    public ResponseEntity<List<RuleModel>> getAllRules() {
        return new ResponseEntity<>(ruleService.getAllRules(), HttpStatus.OK);
    }

    @JsonView(View.GrammarWithoutRules.class)
    @PostMapping("{grammarId}")
    public ResponseEntity<RuleModel> addRule(@RequestBody RuleModel rule, @PathVariable Long grammarId) {
        Grammar grammar = grammarService.getGrammarById(grammarId);
        Pair<RuleModel, Boolean> result = ruleService.processAddRule(rule, grammar);
        return new ResponseEntity<>(result.getValue0(), result.getValue1() ? HttpStatus.CREATED : HttpStatus.OK);

    }

    @JsonView(View.GrammarWithoutRules.class)
    @PostMapping("{grammarId}/batch")
    public ResponseEntity<Set<RuleModel>> addMultipleRules(@RequestBody Set<RuleModel> rules, @PathVariable Long grammarId) {
        Grammar grammar = grammarService.getGrammarById(grammarId);
        Pair<Set<RuleModel>, Boolean> result = ruleService.addRuleMultiple(rules, grammar);
        return new ResponseEntity<>(result.getValue0(), result.getValue1() ? HttpStatus.CREATED : HttpStatus.OK);

    }

    @JsonView(View.GrammarWithoutRules.class)
    @GetMapping("/{id}")
    public ResponseEntity<RuleModel> getRuleById(@PathVariable Long id) {
        return new ResponseEntity<>(ruleService.getById(id), HttpStatus.OK);
    }


    @DeleteMapping("/all")
    public ResponseEntity<?> deleteAllRules() {
        ruleService.deleteRules();
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);

    }

    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteRule(@PathVariable Long id) {
        ruleService.deleteById(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @JsonView(View.GrammarWithoutRules.class)
    @GetMapping("/grammar/{grammarId}")
    public ResponseEntity<Set<RuleModel>> getRulesFromGrammar(@PathVariable Long grammarId) {
        return new ResponseEntity<>(grammarService.getGrammarById(grammarId).getRules(), HttpStatus.OK);
    }

    @JsonView(View.GrammarWithoutRules.class)
    @GetMapping("/grammar/{grammarId}/{ruleId}")
    public ResponseEntity<RuleModel> getRuleFromGrammar(@PathVariable Long grammarId, @PathVariable Long ruleId) {
        RuleModel rule=ruleService.getRuleByRuleIdGrammarID(ruleId,grammarId);
        return new ResponseEntity<>(rule, HttpStatus.OK);
    }


    @JsonView(View.GrammarWithoutRules.class)
    @GetMapping("/left")
    public ResponseEntity<List<RuleModel>> getRuleByLeftSide(@RequestParam() String leftSymbol) {
        return new ResponseEntity<>(ruleService.getByLeftSide(leftSymbol), HttpStatus.OK);
    }

    @JsonView(View.GrammarWithoutRules.class)
    @PutMapping("{id}")
    public ResponseEntity<RuleModel> updateRuleById(@PathVariable Long id, @RequestBody RuleModel rule) {
        return new ResponseEntity<>(ruleService.updateRule(id, rule), HttpStatus.OK);
    }


}
