package com.magistr.app.controller;

import com.magistr.app.config.auth.RequireRoles;
import com.magistr.app.dto.ScheduleRuleDto;
import com.magistr.app.model.Role;
import com.magistr.app.service.ScheduleRuleConflictException;
import com.magistr.app.service.ScheduleRuleService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.LinkedHashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/admin/schedule-rules")
@RequireRoles({Role.ADMIN, Role.EDUCATION_OFFICE})
public class ScheduleRuleAdminController {

    private final ScheduleRuleService scheduleRuleService;

    public ScheduleRuleAdminController(ScheduleRuleService scheduleRuleService) {
        this.scheduleRuleService = scheduleRuleService;
    }

    @GetMapping
    public List<ScheduleRuleDto> getAll(@RequestParam(name = "semesterId", required = false) Long semesterId,
                                        @RequestParam(name = "groupId", required = false) Long groupId) {
        return scheduleRuleService.getAll(semesterId, groupId);
    }

    @GetMapping("/{id}")
    public ResponseEntity<ScheduleRuleDto> getById(@PathVariable("id") Long id) {
        return ResponseEntity.ok(scheduleRuleService.getById(id));
    }

    @PostMapping
    public ResponseEntity<?> create(@RequestBody ScheduleRuleDto request) {
        try {
            return ResponseEntity.ok(scheduleRuleService.create(request));
        } catch (ScheduleRuleConflictException exception) {
            return conflictResponse(exception);
        }
    }

    @PutMapping("/{id}")
    public ResponseEntity<?> update(@PathVariable("id") Long id, @RequestBody ScheduleRuleDto request) {
        try {
            return ResponseEntity.ok(scheduleRuleService.update(id, request));
        } catch (ScheduleRuleConflictException exception) {
            return conflictResponse(exception);
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Map<String, String>> delete(@PathVariable("id") Long id) {
        scheduleRuleService.archive(id);
        return ResponseEntity.ok(Map.of("message", "Правило расписания архивировано"));
    }

    private ResponseEntity<Map<String, Object>> conflictResponse(ScheduleRuleConflictException exception) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("message", exception.getMessage());
        if (exception.getConflictRule() != null) {
            body.put("conflictRule", exception.getConflictRule());
        }
        body.put("conflictFields", exception.getConflictFields());
        body.put("conflictReasons", exception.getConflictReasons());
        return ResponseEntity.status(HttpStatus.CONFLICT).body(body);
    }
}
