package com.pingcap.community.blogserver.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.pingcap.community.blogserver.entity.Notification;
import com.pingcap.community.blogserver.entity.User;
import com.pingcap.community.blogserver.exception.notification.NotificationHaveBeenRead;
import com.pingcap.community.blogserver.exception.notification.NotificationNotFound;
import com.pingcap.community.blogserver.qo.NotificationQuery;
import com.pingcap.community.blogserver.service.NotificationService;
import com.pingcap.community.blogserver.vo.notice.NotificationSummary;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

@RestController
@AllArgsConstructor
@RequestMapping("/api/notifications")
public class NotificationController {

  private final NotificationService notificationService;

  @PreAuthorize("hasAuthority('READ_NOTIFICATION')")
  @JsonView(Notification.NotificationItemView.class)
  @GetMapping
  public Page<Notification> getOwnNotificationList(
    NotificationQuery query,
    @ParameterObject Pageable pageable,
    @Parameter(hidden = true) @AuthenticationPrincipal User viewer
  ) {
    return notificationService.getUserNotificationList(viewer, query, pageable);
  }

  @PreAuthorize("hasAuthority('READ_NOTIFICATION')")
  @GetMapping("/summary")
  public NotificationSummary getOwnNotificationSummary(
      @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date lastReadDate,
      @Parameter(hidden = true) @AuthenticationPrincipal User viewer
  ) {
    return notificationService.getNewNotificationSummary(viewer, lastReadDate);
  }

  @PreAuthorize("hasPermission(#notification, 'NotificationAction:MARK_READ')")
  @PatchMapping("/{id}/read")
  public boolean readNotification(
    @Parameter(schema = @Schema(implementation = Long.class)) @PathVariable("id") Notification notification
  ) throws NotificationNotFound, NotificationHaveBeenRead {
    return notificationService.markNotificationRead(notification);
  }

}
