package com.eactive.testmaster.queue.controller;

import com.eactive.testmaster.queue.dto.QueueHandlerDTO;
import com.eactive.testmaster.queue.dto.QueueHandlerSearch;
import com.eactive.testmaster.queue.entity.QueueHandler;
import com.eactive.testmaster.queue.mapper.QueueHandlerMapper;
import com.eactive.testmaster.queue.service.DynamicQueueManager;
import com.eactive.testmaster.queue.service.QueueHandlerService;
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.ModelAttribute;
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/queue-handlers")
public class QueueHandlerRestController {

    private final QueueHandlerService queueHandlerService;
    private final QueueHandlerMapper queueHandlerMapper;
    private final DynamicQueueManager dynamicQueueManager;

    public QueueHandlerRestController(
        QueueHandlerService queueHandlerService,
        QueueHandlerMapper queueHandlerMapper,
        DynamicQueueManager dynamicQueueManager) {
        this.queueHandlerService = queueHandlerService;
        this.queueHandlerMapper = queueHandlerMapper;
        this.dynamicQueueManager = dynamicQueueManager;
    }

    @GetMapping
    public ResponseEntity<Page<QueueHandlerDTO>> listQueueHandlers(
        @ModelAttribute QueueHandlerSearch queueHandlerSearch,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size);
        Page<QueueHandler> handlers = queueHandlerService.findAll(queueHandlerSearch.buildSpecification(), pageable);
        Page<QueueHandlerDTO> dtoPage = handlers.map(queueHandlerMapper::map);

        return ResponseEntity.ok(dtoPage);
    }

    @GetMapping("/{id}")
    public ResponseEntity<QueueHandler> getQueueHandler(@PathVariable String id) {
        QueueHandler queueHandler = queueHandlerService.findById(id);
        return ResponseEntity.ok(queueHandler);
    }

    @PostMapping
    public ResponseEntity<QueueHandler> createQueueHandler(@RequestBody QueueHandlerDTO dto) {
        QueueHandler queueHandler = queueHandlerMapper.map(dto);
        QueueHandler created = queueHandlerService.create(queueHandler);
        queueHandlerService.initAllQueues();
        return ResponseEntity.ok(created);
    }

    @PostMapping("/update/{id}")
    public ResponseEntity<QueueHandler> updateQueueHandler(
        @PathVariable String id,
        @RequestBody QueueHandlerDTO dto) {

        QueueHandler queueHandler = queueHandlerMapper.map(dto);
        QueueHandler updated = queueHandlerService.update(id, queueHandler);
        queueHandlerService.initAllQueues();
        return ResponseEntity.ok(updated);
    }

    @PostMapping("/delete")
    public ResponseEntity<Void> deleteQueueHandlers(@RequestBody List<String> ids) {
        for (String id : ids) {
            queueHandlerService.deleteById(id);
        }
        queueHandlerService.initAllQueues();
        return ResponseEntity.ok().build();
    }

    @PostMapping("/{id}/start")
    public ResponseEntity<Void> startQueue(@PathVariable String id) {
        QueueHandler queueHandler = queueHandlerService.findById(id);
        dynamicQueueManager.startQueueListener(queueHandler);
        return ResponseEntity.ok().build();
    }

    @PostMapping("/{id}/stop")
    public ResponseEntity<Void> stopQueue(@PathVariable String id) {
        QueueHandler queueHandler = queueHandlerService.findById(id);
        dynamicQueueManager.stopQueueListener(queueHandler.getQueueName());
        return ResponseEntity.ok().build();
    }
}
