package com.gnx.telemedicine.controller;

import com.gnx.telemedicine.dto.admin.AdminStatsResponseDto;
import com.gnx.telemedicine.dto.admin.MetricsResponseDto;
import com.gnx.telemedicine.dto.admin.PaginatedResponse;
import com.gnx.telemedicine.dto.admin.UserManagementDto;
import com.gnx.telemedicine.dto.appointment.AppointmentResponseDto;
import com.gnx.telemedicine.service.AdminService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
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.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/v3/admin")
@RequiredArgsConstructor
@Tag(name = "Admin", description = "Administrative endpoints for system management (Admin role required)")
@SecurityRequirement(name = "bearerAuth")
public class AdminController {
    private final AdminService adminService;

    @Operation(
            summary = "Get all users",
            description = "Retrieve a list of all registered users in the system."
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Users retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            array = @ArraySchema(schema = @Schema(implementation = UserManagementDto.class))
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/users")
    public ResponseEntity<List<UserManagementDto>> getAllUsers() {
        return ResponseEntity.ok(adminService.getAllUsers());
    }

    @Operation(
            summary = "Get all users (paginated)",
            description = """
                    Retrieve a paginated list of all registered users in the system.
                    Supports pagination and sorting.
                    """,
            parameters = {
                    @Parameter(name = "page", description = "Page number (0-indexed)", required = false),
                    @Parameter(name = "size", description = "Page size (1-100)", required = false),
                    @Parameter(name = "sortBy", description = "Field to sort by", required = false),
                    @Parameter(name = "direction", description = "Sort direction (ASC or DESC)", required = false)
            }
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Users retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = PaginatedResponse.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/users/paginated")
    public ResponseEntity<PaginatedResponse<UserManagementDto>> getAllUsersPaginated(
            @RequestParam(required = false, defaultValue = "0") Integer page,
            @RequestParam(required = false, defaultValue = "20") Integer size,
            @RequestParam(required = false) String sortBy,
            @RequestParam(required = false, defaultValue = "ASC") String direction) {
        return ResponseEntity.ok(adminService.getAllUsersPaginated(page, size, sortBy, direction));
    }

    @Operation(
            summary = "Get all patients",
            description = "Retrieve a list of all registered patients in the system."
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Patients retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            array = @ArraySchema(schema = @Schema(implementation = UserManagementDto.class))
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/patients")
    public ResponseEntity<List<UserManagementDto>> getAllPatients() {
        return ResponseEntity.ok(adminService.getAllPatients());
    }

    @Operation(
            summary = "Get all doctors",
            description = "Retrieve a list of all registered doctors in the system."
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Doctors retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            array = @ArraySchema(schema = @Schema(implementation = UserManagementDto.class))
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/doctors")
    public ResponseEntity<List<UserManagementDto>> getAllDoctors() {
        return ResponseEntity.ok(adminService.getAllDoctors());
    }

    @Operation(
            summary = "Get system statistics",
            description = """
                    Retrieve comprehensive system statistics including:
                    - Total users count
                    - Total doctors count
                    - Total patients count
                    - Total appointments count
                    - Active users count
                    """
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Statistics retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = AdminStatsResponseDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/stats")
    public ResponseEntity<AdminStatsResponseDto> getSystemStats() {
        return ResponseEntity.ok(adminService.getSystemStats());
    }

    @Operation(
            summary = "Deactivate a user account",
            description = "Disable a user account",
            parameters = @Parameter(description = "User email", required = true)
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User deactivated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = UserManagementDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @PatchMapping("/users/{email}/deactivate")
    public ResponseEntity<UserManagementDto> deactivateUser(@PathVariable String email) {
        return new ResponseEntity<>(adminService.toggleUserActivity(email, false), HttpStatus.OK);
    }

    @Operation(
            summary = "Activate a user account",
            description = "Enable a user account",
            parameters = @Parameter(description = "User email", required = true)
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User activated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = UserManagementDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @PatchMapping("/users/{email}/activate")
    public ResponseEntity<UserManagementDto> activateUser(@PathVariable String email) {
        return new ResponseEntity<>(adminService.toggleUserActivity(email, true), HttpStatus.OK);
    }

    @Operation(
            summary = "Verify a doctor",
            description = "Mark a doctor as verified",
            parameters = @Parameter(description = "Medical license number", required = true)
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Doctor verified successfully"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @PatchMapping("/doctors/{medicalLicenseNumber}/verify")
    public ResponseEntity<Void> verifyDoctor(@PathVariable String medicalLicenseNumber) {
        adminService.verifyDoctor(medicalLicenseNumber, true);
        return ResponseEntity.ok().build();
    }

    @Operation(
            summary = "Unverify a doctor",
            description = "Mark a doctor as unverified",
            parameters = @Parameter(description = "Medical license number", required = true)
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Doctor unverified successfully"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @PatchMapping("/doctors/{medicalLicenseNumber}/unverify")
    public ResponseEntity<Void> unverifyDoctor(@PathVariable String medicalLicenseNumber) {
        adminService.verifyDoctor(medicalLicenseNumber, false);
        return ResponseEntity.ok().build();
    }

    @Operation(
            summary = "Delete a user",
            description = "Delete a user account",
            parameters = @Parameter(description = "User email", required = true)
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "204",
                    description = "User deleted successfully"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @DeleteMapping("/users/{email}")
    public ResponseEntity<Void> deleteUser(@PathVariable String email) {
        adminService.deleteUser(email);
        return ResponseEntity.noContent().build();
    }

    @Operation(
            summary = "Get all appointments",
            description = "Retrieve a list of all appointments in the system. Admin only."
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Appointments retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            array = @ArraySchema(schema = @Schema(implementation = AppointmentResponseDto.class))
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/appointments")
    public ResponseEntity<List<AppointmentResponseDto>> getAllAppointments() {
        return ResponseEntity.ok(adminService.getAllAppointments());
    }

    @Operation(
            summary = "Get system metrics",
            description = """
                    Retrieve comprehensive system metrics from TelemedicineMetrics including:
                    - Authentication metrics (login attempts, success, failures, 2FA)
                    - Appointment metrics (created, cancelled, completed)
                    - Prescription metrics (created, active)
                    - Message metrics (sent)
                    - API metrics (requests, errors, response times)
                    - Database metrics (query times)
                    - PHI access metrics
                    - Breach notification metrics
                    - User metrics (active, total)
                    """
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Metrics retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = MetricsResponseDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    @GetMapping("/metrics")
    public ResponseEntity<MetricsResponseDto> getMetrics() {
        return ResponseEntity.ok(adminService.getMetrics());
    }

}
