package com.psg.dlsysinfo.dl_sysinfo_server.controller;

import com.psg.dlsysinfo.dl_sysinfo_server.entity.Cve;
import com.psg.dlsysinfo.dl_sysinfo_server.entity.CveMatchResult;
import com.psg.dlsysinfo.dl_sysinfo_server.repository.CveRepository;
import com.psg.dlsysinfo.dl_sysinfo_server.repository.ClientRepository;
import com.psg.dlsysinfo.dl_sysinfo_server.repository.DevicesRepository;
import com.psg.dlsysinfo.dl_sysinfo_server.security.CurrentUser;
import com.psg.dlsysinfo.dl_sysinfo_server.service.VulnerabilityScannerService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/user/vulnerabilities")
@RequiredArgsConstructor
public class UserVulnerabilityController {

    private final VulnerabilityScannerService vulnerabilityScannerService;
    private final CveRepository cveRepository;
    private final DevicesRepository devicesRepository;
    private final ClientRepository clientRepository;

    @PreAuthorize("isAuthenticated()")
    @GetMapping("/{deviceId}")
    public ResponseEntity<Page<CveMatchResult>> getDeviceVulnerabilities(
            @PathVariable Long deviceId,
            @AuthenticationPrincipal CurrentUser user,
            @PageableDefault(size = 25, sort = "score", direction = Sort.Direction.DESC) Pageable pageable
    ) {
        var client = clientRepository.findByClientIdentifier(user.getClientIdentifier())
                .orElseThrow(() -> new RuntimeException("Client not found"));

        var device = devicesRepository.findById(deviceId)
                .orElseThrow(() -> new RuntimeException("Device not found"));

        if (!device.getClient().getClientId().equals(client.getClientId())) {
            throw new RuntimeException("Unauthorized access to device.");
        }

        List<CveMatchResult> all = vulnerabilityScannerService.getVulnerabilitiesForDevice(deviceId);
        int start = (int) pageable.getOffset();
        int end = Math.min((start + pageable.getPageSize()), all.size());
        List<CveMatchResult> paged = all.subList(start, end);

        return ResponseEntity.ok(new PageImpl<>(paged, pageable, all.size()));
    }

    @PreAuthorize("isAuthenticated()")
    @GetMapping
    public ResponseEntity<Page<Cve>> getPaginatedCves(
            @RequestParam(required = false) String severity,
            @RequestParam(required = false) String search,
            @PageableDefault(size = 25, sort = "lastModifiedDate", direction = Sort.Direction.DESC) Pageable pageable
    ) {
        return ResponseEntity.ok(cveRepository.findFiltered(search, pageable));
    }
}
