package com.eactive.testmaster.api.controller;

import com.eactive.testmaster.api.dto.MockRouteDTO;
import com.eactive.testmaster.api.dto.MockRouteRegisterDTO;
import com.eactive.testmaster.api.dto.MockRouteSearch;
import com.eactive.testmaster.api.dto.MockRouteUpdateDTO;
import com.eactive.testmaster.api.entity.MockRoute;
import com.eactive.testmaster.api.mapper.MockRouteMapper;
import com.eactive.testmaster.api.service.MockRouteService;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/mock-routes")
public class MockRouteRestController {

    private final MockRouteService mockRouteService;
    private final MockRouteMapper mockRouteMapper;
    private final MockApiHandlerMapping mockApiHandlerMapping;

    public MockRouteRestController(MockRouteService mockRouteService,
        MockRouteMapper mockRouteMapper,
        MockApiHandlerMapping mockApiHandlerMapping) {
        this.mockRouteService = mockRouteService;
        this.mockRouteMapper = mockRouteMapper;
        this.mockApiHandlerMapping = mockApiHandlerMapping;
    }

    @GetMapping
    public ResponseEntity<Page<MockRouteDTO>> listMockRoutes(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {

        MockRouteSearch search = new MockRouteSearch();
        search.setName(name);

        Pageable pageable = PageRequest.of(page, size);
        Page<MockRoute> routes = mockRouteService.findAll(search.buildSpecification(), pageable);
        Page<MockRouteDTO> dtoPage = routes.map(mockRouteMapper::mapRoute);

        return ResponseEntity.ok(dtoPage);
    }

    @GetMapping("/{id}")
    public ResponseEntity<MockRoute> getMockRoute(@PathVariable Long id) {
        MockRoute mockRoute = mockRouteService.findById(id);
        return ResponseEntity.ok(mockRoute);
    }

    @PostMapping
    public ResponseEntity<MockRoute> createMockRoute(@RequestBody MockRouteRegisterDTO dto) {
        MockRoute mockRoute = mockRouteMapper.map(dto);
        MockRoute created = mockRouteService.create(mockRoute);
        mockRouteService.initAllRoutes();
        mockApiHandlerMapping.registerMapping(created);
        return ResponseEntity.ok(created);
    }

    @PostMapping("/update/{id}")
    public ResponseEntity<MockRoute> updateMockRoute(
        @PathVariable Long id,
        @RequestBody MockRouteUpdateDTO dto) {

        MockRoute prev = mockRouteService.findById(id);
        mockApiHandlerMapping.unregisterMapping(prev);

        MockRoute mockRoute = mockRouteMapper.map(dto);
        MockRoute updated = mockRouteService.update(id, mockRoute);
        mockRouteService.initAllRoutes();

        mockApiHandlerMapping.registerMapping(updated);
        return ResponseEntity.ok(updated);
    }

    @PostMapping("/delete")
    public ResponseEntity<Void> deleteMockRoutes(@RequestBody List<Long> ids) {
        for (Long id : ids) {
            MockRoute mockRoute = mockRouteService.findById(id);
            mockApiHandlerMapping.unregisterMapping(mockRoute);
            mockRouteService.deleteById(id);
        }
        mockRouteService.initAllRoutes();
        return ResponseEntity.ok().build();
    }


}
