package com.mosquito.project.controller;

import com.mosquito.project.dto.ShortenRequest;
import com.mosquito.project.dto.ShortenResponse;
import com.mosquito.project.persistence.entity.ShortLinkEntity;
import com.mosquito.project.service.ShortLinkService;
import com.mosquito.project.persistence.repository.LinkClickRepository;
import com.mosquito.project.web.UrlValidator;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class ShortLinkController {

    private static final Logger log = LoggerFactory.getLogger(ShortLinkController.class);

    private final ShortLinkService shortLinkService;
    private final LinkClickRepository linkClickRepository;
    private final UrlValidator urlValidator;

    public ShortLinkController(ShortLinkService shortLinkService, LinkClickRepository linkClickRepository, UrlValidator urlValidator) {
        this.shortLinkService = shortLinkService;
        this.linkClickRepository = linkClickRepository;
        this.urlValidator = urlValidator;
    }

    @PostMapping("/api/v1/internal/shorten")
    public ResponseEntity<ShortenResponse> shorten(@Valid @RequestBody ShortenRequest request) {
        ShortLinkEntity e = shortLinkService.create(request.getOriginalUrl());
        ShortenResponse resp = new ShortenResponse(e.getCode(), "/r/" + e.getCode(), e.getOriginalUrl());
        return new ResponseEntity<>(resp, HttpStatus.CREATED);
    }

    @GetMapping("/r/{code}")
    public ResponseEntity<Void> redirect(@PathVariable String code, jakarta.servlet.http.HttpServletRequest request) {
        var linkOpt = shortLinkService.findByCode(code);
        if (linkOpt.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }

        var e = linkOpt.get();
        String originalUrl = e.getOriginalUrl();

        if (!urlValidator.isAllowedUrl(originalUrl)) {
            log.warn("Blocked potentially malicious redirect attempt. Code: {}, URL: {}", code, originalUrl);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }

        try {
            com.mosquito.project.persistence.entity.LinkClickEntity click = new com.mosquito.project.persistence.entity.LinkClickEntity();
            click.setCode(code);
            click.setActivityId(e.getActivityId());
            click.setInviterUserId(e.getInviterUserId());
            String ip = request.getHeader("X-Forwarded-For");
            if (ip != null && !ip.isBlank()) {
                ip = ip.split(",")[0].trim();
            } else {
                ip = request.getRemoteAddr();
            }
            click.setIp(ip);
            click.setUserAgent(request.getHeader("User-Agent"));
            click.setReferer(request.getHeader("Referer"));
            click.setCreatedAt(java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC));
            linkClickRepository.save(click);
        } catch (Exception ex) {
            log.error("Failed to record link click for code {}: {}", code, ex.getMessage(), ex);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.LOCATION, originalUrl);
        return new ResponseEntity<>(headers, HttpStatus.FOUND);
    }
}
