package com.saas.shared.controller;

import com.saas.shared.service.BaseCrudService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Base CRUD controller providing standard REST endpoints
 * 
 * @param <T>         Entity type
 * @param <ID>        ID type (usually Long)
 * @param <CreateReq> Create request DTO
 * @param <UpdateReq> Update request DTO
 * @param <Response>  Response DTO
 */
public abstract class BaseCrudController<T, ID, CreateReq, UpdateReq, Response> {

    /**
     * Get the service instance for this controller
     * Must be implemented by concrete controllers
     */
    protected abstract BaseCrudService<T, ID, CreateReq, UpdateReq, Response> getService();

    /**
     * GET /{id} - Get entity by ID
     */
    @GetMapping("/{id}")
    public ResponseEntity<Response> getById(@PathVariable ID id) {
        return ResponseEntity.ok(getService().getById(id));
    }

    /**
     * GET / - Get all entities
     */
    @GetMapping
    public ResponseEntity<List<Response>> getAll() {
        return ResponseEntity.ok(getService().getAll());
    }

    /**
     * POST / - Create new entity
     */
    @PostMapping
    public ResponseEntity<Response> create(@Valid @RequestBody CreateReq request) {
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(getService().create(request));
    }

    /**
     * PUT /{id} - Update existing entity
     */
    @PutMapping("/{id}")
    public ResponseEntity<Response> update(
            @PathVariable ID id,
            @Valid @RequestBody UpdateReq request) {
        return ResponseEntity.ok(getService().update(id, request));
    }

    /**
     * DELETE /{id} - Delete entity
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable ID id) {
        getService().delete(id);
        return ResponseEntity.noContent().build();
    }
}
