package com.toyshop.controller.admin;

import com.toyshop.dto.*;
import com.toyshop.entity.*;
import com.toyshop.repository.*;
import com.toyshop.service.ProductService;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/admin")
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
  private final UserRepository userRepository;
  private final CategoryRepository categoryRepository;
  private final ProductRepository productRepository;
  private final ProductImageRepository productImageRepository;
  private final OrderRepository orderRepository;
  private final CarouselRepository carouselRepository;
  private final NoticeRepository noticeRepository;
  private final ProductService productService;

  public AdminController(UserRepository userRepository, CategoryRepository categoryRepository,
                         ProductRepository productRepository, ProductImageRepository productImageRepository,
                         OrderRepository orderRepository, CarouselRepository carouselRepository,
                         NoticeRepository noticeRepository, ProductService productService) {
    this.userRepository = userRepository;
    this.categoryRepository = categoryRepository;
    this.productRepository = productRepository;
    this.productImageRepository = productImageRepository;
    this.orderRepository = orderRepository;
    this.carouselRepository = carouselRepository;
    this.noticeRepository = noticeRepository;
    this.productService = productService;
  }

  @GetMapping("/users")
  public ApiResponse<List<User>> users() {
    return ApiResponse.ok(userRepository.findAll());
  }

  @PutMapping("/users/{id}")
  public ApiResponse<User> updateUserStatus(@PathVariable Long id, @Valid @RequestBody UserStatusRequest request) {
    User user = userRepository.findById(id).orElseThrow();
    user.setEnabled(request.getEnabled());
    return ApiResponse.ok(userRepository.save(user));
  }

  @GetMapping("/categories")
  public ApiResponse<List<Category>> categories() {
    return ApiResponse.ok(categoryRepository.findAll());
  }

  @PostMapping("/categories")
  public ApiResponse<Category> createCategory(@Valid @RequestBody CategoryRequest request) {
    if (categoryRepository.existsByName(request.getName())) {
      return ApiResponse.fail("分类已存在");
    }
    Category category = new Category();
    category.setName(request.getName());
    category.setDescription(request.getDescription());
    return ApiResponse.ok(categoryRepository.save(category));
  }

  @PutMapping("/categories/{id}")
  public ApiResponse<Category> updateCategory(@PathVariable Long id, @Valid @RequestBody CategoryRequest request) {
    Category category = categoryRepository.findById(id).orElseThrow();
    category.setName(request.getName());
    category.setDescription(request.getDescription());
    return ApiResponse.ok(categoryRepository.save(category));
  }

  @DeleteMapping("/categories/{id}")
  public ApiResponse<?> deleteCategory(@PathVariable Long id) {
    categoryRepository.deleteById(id);
    return ApiResponse.ok("删除成功", null);
  }

  @GetMapping("/products")
  public ApiResponse<List<Product>> products() {
    List<Product> products = productRepository.findAll();
    for (Product product : products) {
      var img = productService.getFirstImage(product);
      if (img != null) {
        product.setImageUrl(img.getUrl());
      }
    }
    return ApiResponse.ok(products);
  }

  @PostMapping("/products")
  public ApiResponse<Product> createProduct(@Valid @RequestBody ProductRequest request) {
    Product product = new Product();
    product.setName(request.getName());
    product.setDescription(request.getDescription());
    product.setPrice(request.getPrice());
    product.setStock(request.getStock());
    product.setAgeRange(request.getAgeRange());
    product.setSafetyInfo(request.getSafetyInfo());
    product.setOnSale(request.isOnSale());
    if (request.getCategoryId() != null) {
      product.setCategory(productService.getCategory(request.getCategoryId()));
    }
    return ApiResponse.ok(productRepository.save(product));
  }

  @PutMapping("/products/{id}")
  public ApiResponse<Product> updateProduct(@PathVariable Long id, @Valid @RequestBody ProductRequest request) {
    Product product = productRepository.findById(id).orElseThrow();
    product.setName(request.getName());
    product.setDescription(request.getDescription());
    if (request.getPrice() != null) {
      product.setPrice(request.getPrice());
    }
    if (request.getStock() != null) {
      product.setStock(request.getStock());
    }
    product.setAgeRange(request.getAgeRange());
    product.setSafetyInfo(request.getSafetyInfo());
    product.setOnSale(request.isOnSale());
    if (request.getCategoryId() != null) {
      product.setCategory(productService.getCategory(request.getCategoryId()));
    }
    return ApiResponse.ok(productRepository.save(product));
  }

  @DeleteMapping("/products/{id}")
  public ApiResponse<?> deleteProduct(@PathVariable Long id) {
    productRepository.deleteById(id);
    return ApiResponse.ok("删除成功", null);
  }

  @GetMapping("/products/{id}/images")
  public ApiResponse<List<ProductImage>> productImages(@PathVariable Long id) {
    Product product = productRepository.findById(id).orElseThrow();
    return ApiResponse.ok(productImageRepository.findByProduct(product));
  }

  @PostMapping("/products/{id}/images")
  public ApiResponse<ProductImage> addProductImage(@PathVariable Long id, @RequestBody ProductImage body) {
    Product product = productRepository.findById(id).orElseThrow();
    ProductImage image = new ProductImage();
    image.setProduct(product);
    image.setUrl(body.getUrl());
    image.setSortOrder(body.getSortOrder() == null ? 0 : body.getSortOrder());
    return ApiResponse.ok(productImageRepository.save(image));
  }

  @DeleteMapping("/product-images/{imageId}")
  public ApiResponse<?> deleteProductImage(@PathVariable Long imageId) {
    productImageRepository.deleteById(imageId);
    return ApiResponse.ok("删除成功", null);
  }

  @PutMapping("/products/{id}/image")
  public ApiResponse<?> replaceProductImage(@PathVariable Long id, @RequestBody ProductImage body) {
    Product product = productRepository.findById(id).orElseThrow();
    if (body.getUrl() == null || body.getUrl().isBlank()) {
      return ApiResponse.fail("图片地址不能为空");
    }
    productService.replaceProductImage(product, body.getUrl());
    return ApiResponse.ok("更新成功", null);
  }

  @GetMapping("/orders")
  public ApiResponse<List<Order>> orders() {
    return ApiResponse.ok(orderRepository.findAll());
  }

  @PutMapping("/orders/status")
  public ApiResponse<Order> updateOrderStatus(@Valid @RequestBody AdminOrderUpdateRequest request) {
    Order order = orderRepository.findById(request.getOrderId()).orElseThrow();
    order.setStatus(OrderStatus.valueOf(request.getStatus()));
    order.setLogisticsNo(request.getLogisticsNo());
    return ApiResponse.ok(orderRepository.save(order));
  }

  @GetMapping("/carousels")
  public ApiResponse<List<Carousel>> carousels() {
    return ApiResponse.ok(carouselRepository.findAllByOrderBySortOrderAsc());
  }

  @PostMapping("/carousels")
  public ApiResponse<Carousel> createCarousel(@Valid @RequestBody CarouselRequest request) {
    Carousel carousel = new Carousel();
    carousel.setImageUrl(request.getImageUrl());
    carousel.setLinkUrl(request.getLinkUrl());
    carousel.setSortOrder(request.getSortOrder());
    return ApiResponse.ok(carouselRepository.save(carousel));
  }

  @PutMapping("/carousels/{id}")
  public ApiResponse<Carousel> updateCarousel(@PathVariable Long id, @Valid @RequestBody CarouselRequest request) {
    Carousel carousel = carouselRepository.findById(id).orElseThrow();
    carousel.setImageUrl(request.getImageUrl());
    carousel.setLinkUrl(request.getLinkUrl());
    carousel.setSortOrder(request.getSortOrder());
    return ApiResponse.ok(carouselRepository.save(carousel));
  }

  @DeleteMapping("/carousels/{id}")
  public ApiResponse<?> deleteCarousel(@PathVariable Long id) {
    carouselRepository.deleteById(id);
    return ApiResponse.ok("删除成功", null);
  }

  @GetMapping("/notices")
  public ApiResponse<List<Notice>> notices() {
    return ApiResponse.ok(noticeRepository.findAll());
  }

  @PostMapping("/notices")
  public ApiResponse<Notice> createNotice(@Valid @RequestBody NoticeRequest request) {
    Notice notice = new Notice();
    notice.setTitle(request.getTitle());
    notice.setContent(request.getContent());
    return ApiResponse.ok(noticeRepository.save(notice));
  }

  @PutMapping("/notices/{id}")
  public ApiResponse<Notice> updateNotice(@PathVariable Long id, @Valid @RequestBody NoticeRequest request) {
    Notice notice = noticeRepository.findById(id).orElseThrow();
    notice.setTitle(request.getTitle());
    notice.setContent(request.getContent());
    return ApiResponse.ok(noticeRepository.save(notice));
  }

  @DeleteMapping("/notices/{id}")
  public ApiResponse<?> deleteNotice(@PathVariable Long id) {
    noticeRepository.deleteById(id);
    return ApiResponse.ok("删除成功", null);
  }
}
