package cz.muni.fi.pa165.core.user.roles;

import cz.muni.fi.pa165.core.helpers.exceptions.EntityDeletionException;
import cz.muni.fi.pa165.model.dto.common.Result;
import cz.muni.fi.pa165.model.dto.role.CompanyRoleDto;
import cz.muni.fi.pa165.model.dto.role.HouseRoleDto;
import cz.muni.fi.pa165.model.dto.role.RoleDto;
import cz.muni.fi.pa165.model.dto.user.UserDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "Role", description = "Role API")
@RestController
@RequestMapping("/api/role")
public class RoleController {

    private final  RoleService roleService;
    private final RoleFacade roleFacade;
    @Autowired
    public RoleController(RoleService roleService, RoleFacade roleFacade){
        this.roleService = roleService;
        this.roleFacade = roleFacade;
    }

    @Operation(
            summary = "Create house role",
            description = "Creates a new user roles",
            tags = {"role"})
    @ApiResponses(
            value = {
                    @ApiResponse(
                            responseCode = "201",
                            description = "Role created",
                            content = {
                                    @Content(
                                            mediaType = "application/json",
                                            schema = @Schema(implementation = HouseRoleDto.class))
                            }),
                    @ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
            })
    @PostMapping("/house-role")
    public HouseRoleDto createHouseRole(
            @Parameter(description = "Role to be created") @RequestBody HouseRoleDto roleDto) {
        return roleFacade.createHouseRole(roleDto);
    }

    @Operation(
            summary = "Create company role",
            description = "Creates a new user roles",
            tags = {"role"})
    @ApiResponses(
            value = {
                    @ApiResponse(
                            responseCode = "201",
                            description = "Role created",
                            content = {
                                    @Content(
                                            mediaType = "application/json",
                                            schema = @Schema(implementation = CompanyRoleDto.class))
                            }),
                    @ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
            })
    @PostMapping("/company-role")
    public CompanyRoleDto createCompanyRole(
            @Parameter(description = "Role to be created") @RequestBody CompanyRoleDto roleDto) {
        return roleFacade.createCompanyRole(roleDto);
    }

    @Operation(
            summary = "Create general role",
            description = "Creates a new user roles",
            tags = {"role"})
    @ApiResponses(
            value = {
                    @ApiResponse(
                            responseCode = "201",
                            description = "Role created",
                            content = {
                                    @Content(
                                            mediaType = "application/json",
                                            schema = @Schema(implementation = RoleDto.class))
                            }),
                    @ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
            })
    @PostMapping("/general-role")
    public RoleDto createGeneralRole(
            @Parameter(description = "Role to be created") @RequestBody RoleDto roleDto) {
        return roleFacade.createGeneralRole(roleDto);
    }


    @DeleteMapping("/{id}")
    @Operation(summary = "Delete a user role")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Role deleted successfully"),
            @ApiResponse(responseCode = "404", description = "Role not found"),
            @ApiResponse(responseCode = "422", description = "Role could not be deleted"),
            @ApiResponse(responseCode = "500", description = "Internal server error")
    })
    public ResponseEntity<?> deleteCompanyRoleById(
            @Parameter(description = "ID of the role to be deleted") @PathVariable String id) {
        try {
            return ResponseEntity.status(HttpStatus.OK).body(roleFacade.deleteCompanyRole(id));
        } catch (EntityDeletionException ex) {
            return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY)
                    .body(ex.getMessage());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Error occured");
        }
    }

    @Operation(
            summary = "Get all user roles",
            description = "Returns all user roles",
            tags = {"role"})
    @ApiResponses(
            value = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Roles found",
                            content = {
                                    @Content(
                                            mediaType = "application/json",
                                            schema = @Schema(implementation = RoleDto.class))
                            })
            })
    @GetMapping
    public List<RoleDto> findUserRoles(
            @Parameter(description = "Page number of results to retrieve") @RequestParam String userId) {
        return roleFacade.findAllByUser(userId);
    }
}
