package kz.konturai.parser.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import kz.konturai.parser.dto.*;
import kz.konturai.parser.model.SocialMediaCredentials;
import kz.konturai.parser.service.JwtService;
import kz.konturai.parser.service.SocialMediaCredentialsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/social-media/credentials")
public class SocialMediaCredentialsController {

        private static final Logger logger = LoggerFactory.getLogger(SocialMediaCredentialsController.class);

        private final SocialMediaCredentialsService credentialsService;
        private final JwtService jwtService;
        private final ObjectMapper objectMapper;

        public SocialMediaCredentialsController(
                        SocialMediaCredentialsService credentialsService,
                        JwtService jwtService) {
                this.credentialsService = credentialsService;
                this.jwtService = jwtService;
                this.objectMapper = new ObjectMapper();
        }

        private String extractUserIdFromHeader(String authHeader) {
                if (authHeader == null || authHeader.isEmpty()) {
                        return null;
                }
                return jwtService.extractUserIdFromHeader(authHeader);
        }

        private ResponseEntity<?> unauthorizedResponse() {
                ErrorResponse error = new ErrorResponse(
                                "UNAUTHORIZED",
                                "Требуется аутентификация. Пожалуйста, предоставьте валидный JWT токен.");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                                .body(ApiResponse.error("Не авторизован", error));
        }

        /**
         * Сохранение или обновление credentials для платформы
         * POST /api/social-media/credentials
         */
        @PostMapping
        public ResponseEntity<?> saveCredentials(
                        @RequestHeader(value = "Authorization", required = false) String authHeader,
                        @Valid @RequestBody SocialMediaCredentialsRequest request) {

                String userId = extractUserIdFromHeader(authHeader);
                if (userId == null) {
                        return unauthorizedResponse();
                }

                try {
                        // Конвертируем credentials в строку: если это String - используем как есть,
                        // если Object - сериализуем в JSON
                        String credentialsString = convertCredentialsToString(request.getCredentials());

                        SocialMediaCredentials credentials = credentialsService.saveCredentials(
                                        userId,
                                        request.getPlatform(),
                                        credentialsString);

                        SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
                                        credentials.getPlatform(),
                                        true,
                                        credentials.getCreatedAt(),
                                        credentials.getUpdatedAt());

                        return ResponseEntity.ok(ApiResponse.success(
                                        "Credentials успешно сохранены для платформы " + request.getPlatform(),
                                        response));

                } catch (IllegalArgumentException e) {
                        ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
                        return ResponseEntity.badRequest()
                                        .body(ApiResponse.error("Ошибка валидации", error));
                } catch (Exception e) {
                        ErrorResponse error = new ErrorResponse(
                                        "INTERNAL_SERVER_ERROR",
                                        "Произошла ошибка при сохранении credentials");
                        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                        .body(ApiResponse.error("Внутренняя ошибка сервера", error));
                }
        }

        /**
         * Получение информации о credentials для платформы
         * GET /api/social-media/credentials/{platform}
         */
        @GetMapping("/{platform}")
        public ResponseEntity<?> getCredentials(
                        @RequestHeader(value = "Authorization", required = false) String authHeader,
                        @PathVariable String platform) {

                String userId = extractUserIdFromHeader(authHeader);
                if (userId == null) {
                        return unauthorizedResponse();
                }

                boolean hasCredentials = credentialsService.hasCredentials(userId, platform);
                SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
                                platform,
                                hasCredentials);

                return ResponseEntity.ok(ApiResponse.success(response));
        }

        /**
         * Получение списка всех платформ с credentials
         * GET /api/social-media/credentials
         */
        @GetMapping
        public ResponseEntity<?> getAllCredentials(
                        @RequestHeader(value = "Authorization", required = false) String authHeader) {

                String userId = extractUserIdFromHeader(authHeader);
                if (userId == null) {
                        return unauthorizedResponse();
                }

                List<SocialMediaCredentials> credentialsList = credentialsService.getUserCredentials(userId);
                List<SocialMediaCredentialsResponse> responseList = credentialsList.stream()
                                .map(cred -> new SocialMediaCredentialsResponse(
                                                cred.getPlatform(),
                                                true,
                                                cred.getCreatedAt(),
                                                cred.getUpdatedAt()))
                                .collect(Collectors.toList());

                return ResponseEntity.ok(ApiResponse.success(responseList));
        }

        /**
         * Удаление credentials для платформы
         * DELETE /api/social-media/credentials/{platform}
         */
        @DeleteMapping("/{platform}")
        public ResponseEntity<?> deleteCredentials(
                        @RequestHeader(value = "Authorization", required = false) String authHeader,
                        @PathVariable String platform) {

                String userId = extractUserIdFromHeader(authHeader);
                if (userId == null) {
                        return unauthorizedResponse();
                }

                try {
                        if (!credentialsService.hasCredentials(userId, platform)) {
                                ErrorResponse error = new ErrorResponse(
                                                "NOT_FOUND",
                                                "Credentials для платформы " + platform + " не найдены");
                                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                                                .body(ApiResponse.error("Credentials не найдены", error));
                        }

                        credentialsService.deleteCredentials(userId, platform);

                        return ResponseEntity.ok(ApiResponse.success(
                                        "Credentials для платформы " + platform + " успешно удалены",
                                        null));

                } catch (IllegalArgumentException e) {
                        ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
                        return ResponseEntity.badRequest()
                                        .body(ApiResponse.error("Ошибка валидации", error));
                } catch (Exception e) {
                        ErrorResponse error = new ErrorResponse(
                                        "INTERNAL_SERVER_ERROR",
                                        "Произошла ошибка при удалении credentials");
                        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                        .body(ApiResponse.error("Внутренняя ошибка сервера", error));
                }
        }

        @ExceptionHandler(MethodArgumentNotValidException.class)
        public ResponseEntity<ApiResponse<ErrorResponse>> handleValidationException(
                        MethodArgumentNotValidException ex) {

                Map<String, String> details = new HashMap<>();
                ex.getBindingResult().getFieldErrors().forEach(error -> {
                        details.put(error.getField(), error.getDefaultMessage());
                });

                ErrorResponse errorResponse = new ErrorResponse(
                                "VALIDATION_ERROR",
                                "Ошибка валидации входных данных",
                                details);

                return ResponseEntity.badRequest()
                                .body(ApiResponse.error("Ошибка валидации", errorResponse));
        }

        @ExceptionHandler(Exception.class)
        public ResponseEntity<ApiResponse<ErrorResponse>> handleGenericException(Exception e) {
                ErrorResponse errorResponse = new ErrorResponse(
                                "INTERNAL_SERVER_ERROR",
                                "Произошла внутренняя ошибка сервера. Попробуйте позже.");

                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                .body(ApiResponse.error("Внутренняя ошибка сервера", errorResponse));
        }

        /**
         * Конвертирует credentials (Object или String) в строку для сохранения
         * Если это String - возвращает как есть
         * Если это Object - сериализует в JSON строку
         */
        private String convertCredentialsToString(Object credentials) {
                if (credentials == null) {
                        throw new IllegalArgumentException("Credentials cannot be null");
                }

                if (credentials instanceof String) {
                        return (String) credentials;
                }

                try {
                        // Сериализуем объект в JSON строку
                        return objectMapper.writeValueAsString(credentials);
                } catch (Exception e) {
                        logger.error("Failed to serialize credentials to JSON", e);
                        throw new IllegalArgumentException("Failed to serialize credentials: " + e.getMessage(), e);
                }
        }
}
