package com.walkguide.controller;

import com.walkguide.dto.ApiResponse;
import com.walkguide.dto.request.*;
import com.walkguide.dto.response.*;
import com.walkguide.enums.ActivityLogType;
import com.walkguide.repository.UserRepository;
import com.walkguide.security.SecurityHelper;
import com.walkguide.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/v1/user")
@RequiredArgsConstructor
public class UserController {

    private final LocationService locationService;
    private final ObstacleLogService obstacleLogService;
    private final SosService sosService;
    private final ActivityLogService activityLogService;
    private final NotificationService notificationService;
    private final UserSettingsService userSettingsService;
    private final AiConfigService aiConfigService;
    private final VoiceCommandService voiceCommandService;
    private final HardwareShortcutService hardwareShortcutService;
    private final UserRepository userRepository;

    @GetMapping("/profile")
    public ResponseEntity<ApiResponse<?>> getProfile() {
        Long userId = SecurityHelper.getCurrentUserId();
        var user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("User tidak ditemukan"));
        var profile = java.util.Map.of(
                "id", user.getId(),
                "email", user.getEmail(),
                "displayName", user.getDisplayName() != null ? user.getDisplayName() : "",
                "role", user.getRole(),
                "uniqueUserId", user.getUniqueUserId() != null ? user.getUniqueUserId() : ""
        );
        return ResponseEntity.ok(ApiResponse.ok(profile, "Profil user"));
    }

    @GetMapping("/settings")
    public ResponseEntity<ApiResponse<UserSettingsResponse>> getSettings() {
        return ResponseEntity.ok(ApiResponse.ok(
                userSettingsService.getSettings(SecurityHelper.getCurrentUserId()),
                "Settings user"));
    }

    @PutMapping("/settings")
    public ResponseEntity<ApiResponse<UserSettingsResponse>> updateSettings(
            @RequestBody UserSettingsUpdateRequest req) {
        return ResponseEntity.ok(ApiResponse.ok(
                userSettingsService.updateSettings(SecurityHelper.getCurrentUserId(), req),
                "Settings diperbarui"));
    }

    @GetMapping("/voice-commands")
    public ResponseEntity<ApiResponse<List<VoiceCommandResponse>>> getVoiceCommands() {
        return ResponseEntity.ok(ApiResponse.ok(
                voiceCommandService.getAll(SecurityHelper.getCurrentUserId()),
                "Voice commands"));
    }

    @GetMapping("/shortcuts")
    public ResponseEntity<ApiResponse<List<HardwareShortcutResponse>>> getShortcuts() {
        return ResponseEntity.ok(ApiResponse.ok(
                hardwareShortcutService.getAll(SecurityHelper.getCurrentUserId()),
                "Hardware shortcuts"));
    }

    @PutMapping("/shortcuts")
    public ResponseEntity<ApiResponse<HardwareShortcutResponse>> updateShortcut(
            @RequestBody HardwareShortcutUpdateRequest req) {
        return ResponseEntity.ok(ApiResponse.ok(
                hardwareShortcutService.update(SecurityHelper.getCurrentUserId(), req),
                "Shortcut diperbarui"));
    }

    @GetMapping("/ai-config")
    public ResponseEntity<ApiResponse<AiConfigResponse>> getAiConfig() {
        return ResponseEntity.ok(ApiResponse.ok(
                aiConfigService.getConfig(SecurityHelper.getCurrentUserId()),
                "AI config"));
    }

    @PostMapping("/location")
    public ResponseEntity<ApiResponse<LocationResponse>> updateLocation(
            @RequestBody LocationUpdateRequest req) {
        return ResponseEntity.ok(ApiResponse.ok(
                locationService.updateLocation(SecurityHelper.getCurrentUserId(), req),
                "Lokasi diperbarui"));
    }

    @PostMapping("/obstacle")
    public ResponseEntity<ApiResponse<ObstacleLogResponse>> logObstacle(
            @RequestBody ObstacleLogRequest req) {
        return ResponseEntity.ok(ApiResponse.ok(
                obstacleLogService.saveObstacle(SecurityHelper.getCurrentUserId(), req),
                "Obstacle dicatat"));
    }

    @PostMapping("/sos")
    public ResponseEntity<ApiResponse<SosEventResponse>> triggerSos(
            @RequestBody SosRequest req) {
        return ResponseEntity.ok(ApiResponse.ok(
                sosService.triggerSos(SecurityHelper.getCurrentUserId(), req),
                "SOS dikirim! Guardian sudah diberitahu."));
    }

    @GetMapping("/activity-logs")
    public ResponseEntity<ApiResponse<Page<ActivityLogResponse>>> getActivityLogs(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        return ResponseEntity.ok(ApiResponse.ok(
                activityLogService.getLogs(SecurityHelper.getCurrentUserId(),
                        PageRequest.of(page, size)), "Log aktivitas"));
    }

    @GetMapping("/notifications")
    public ResponseEntity<ApiResponse<Page<NotificationResponse>>> getNotifications(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        return ResponseEntity.ok(ApiResponse.ok(
                notificationService.getNotifications(SecurityHelper.getCurrentUserId(),
                        PageRequest.of(page, size)), "Notifikasi"));
    }

    @GetMapping("/notifications/unread-count")
    public ResponseEntity<ApiResponse<Long>> getUnreadCount() {
        return ResponseEntity.ok(ApiResponse.ok(
                notificationService.getUnreadCount(SecurityHelper.getCurrentUserId()),
                "Jumlah notifikasi belum dibaca"));
    }

    @PutMapping("/notifications/mark-all-read")
    public ResponseEntity<ApiResponse<Void>> markAllRead() {
        notificationService.markAllRead(SecurityHelper.getCurrentUserId());
        return ResponseEntity.ok(ApiResponse.ok(null, "Semua notifikasi ditandai sudah dibaca"));
    }

    @PutMapping("/notifications/{id}/read")
    public ResponseEntity<ApiResponse<Void>> markOneRead(@PathVariable Long id) {
        notificationService.markOneRead(id);
        return ResponseEntity.ok(ApiResponse.ok(null, "Notifikasi ditandai sudah dibaca"));
    }

    @PostMapping("/walkguide/start")
    public ResponseEntity<ApiResponse<Void>> walkGuideStart() {
        Long userId = SecurityHelper.getCurrentUserId();
        userRepository.findById(userId).ifPresent(u ->
                activityLogService.createLog(u, ActivityLogType.WALKGUIDE_START,
                        "WalkGuide dimulai", null));
        return ResponseEntity.ok(ApiResponse.ok(null, "WalkGuide dimulai"));
    }

    @PostMapping("/walkguide/stop")
    public ResponseEntity<ApiResponse<Void>> walkGuideStop() {
        Long userId = SecurityHelper.getCurrentUserId();
        userRepository.findById(userId).ifPresent(u ->
                activityLogService.createLog(u, ActivityLogType.WALKGUIDE_STOP,
                        "WalkGuide dihentikan", null));
        return ResponseEntity.ok(ApiResponse.ok(null, "WalkGuide dihentikan"));
    }
}
