package com.petshop.backend.controller;

import com.petshop.backend.dto.adoption.AdoptionRequest;
import com.petshop.backend.dto.adoption.AdoptionResponse;
import com.petshop.backend.dto.adoption.CustomerAdoptionRequest;
import com.petshop.backend.dto.common.BulkDeleteRequest;
import com.petshop.backend.entity.User;
import com.petshop.backend.repository.UserRepository;
import com.petshop.backend.service.AdoptionService;
import com.petshop.backend.util.AuthenticationHelper;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;

@RestController
@RequestMapping("/api/v1/adoptions")
public class AdoptionController {

    private final AdoptionService adoptionService;
    private final UserRepository userRepository;

    public AdoptionController(AdoptionService adoptionService, UserRepository userRepository) {
        this.adoptionService = adoptionService;
        this.userRepository = userRepository;
    }

    @GetMapping
    @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
    public ResponseEntity<Page<AdoptionResponse>> getAllAdoptions(
            @RequestParam(required = false) String q,
            @RequestParam(required = false) Long customerId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) Long storeId,
            @RequestParam(required = false) String date,
            Pageable pageable) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String role = authentication.getAuthorities().stream()
                .findFirst()
                .map(authority -> authority.getAuthority().replace("ROLE_", ""))
                .orElse(null);

        Long effectiveCustomerId = customerId;
        if (role != null && role.equals("CUSTOMER")) {
            User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
            effectiveCustomerId = user.getId();
        }

        LocalDate adoptionDate = (date != null && !date.isBlank()) ? LocalDate.parse(date) : null;

        return ResponseEntity.ok(adoptionService.getAllAdoptions(q, effectiveCustomerId, status, storeId, adoptionDate, pageable));
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
    public ResponseEntity<AdoptionResponse> getAdoptionById(@PathVariable Long id) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String role = authentication.getAuthorities().stream()
                .findFirst()
                .map(authority -> authority.getAuthority().replace("ROLE_", ""))
                .orElse(null);

        Long customerId = null;
        if (role != null && role.equals("CUSTOMER")) {
            User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
            customerId = user.getId();
        }

        return ResponseEntity.ok(adoptionService.getAdoptionById(id, customerId));
    }

    @PostMapping
    @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
    public ResponseEntity<AdoptionResponse> createAdoption(@Valid @RequestBody AdoptionRequest request) {
        return ResponseEntity.status(HttpStatus.CREATED).body(adoptionService.createAdoption(request));
    }

    @PostMapping("/request")
    @PreAuthorize("hasAnyRole('CUSTOMER', 'ADMIN')")
    public ResponseEntity<AdoptionResponse> requestAdoption(@Valid @RequestBody CustomerAdoptionRequest request) {
        User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
        return ResponseEntity.status(HttpStatus.CREATED).body(
                adoptionService.requestAdoption(user.getId(), request.getPetId(), request.getEmployeeId(), request.getSourceStoreId(), request.getAdoptionDate())
        );
    }

    @PatchMapping("/{id}/cancel")
    @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
    public ResponseEntity<AdoptionResponse> cancelAdoption(@PathVariable Long id) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String role = authentication.getAuthorities().stream()
                .findFirst()
                .map(authority -> authority.getAuthority().replace("ROLE_", ""))
                .orElse(null);

        Long customerId = null;
        if ("CUSTOMER".equals(role)) {
            User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
            customerId = user.getId();
        }

        return ResponseEntity.ok(adoptionService.cancelAdoption(id, customerId));
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
    public ResponseEntity<AdoptionResponse> updateAdoption(
            @PathVariable Long id,
            @Valid @RequestBody AdoptionRequest request) {
        return ResponseEntity.ok(adoptionService.updateAdoption(id, request));
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
    public ResponseEntity<Void> deleteAdoption(@PathVariable Long id) {
        adoptionService.deleteAdoption(id);
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Void> bulkDeleteAdoptions(@Valid @RequestBody BulkDeleteRequest request) {
        adoptionService.bulkDeleteAdoptions(request);
        return ResponseEntity.noContent().build();
    }
}
