package cn.novalon.gym.manage.notify.handler;

import cn.novalon.gym.manage.notify.core.domain.SysNotice;
import cn.novalon.gym.manage.notify.core.service.ISysNoticeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
@Tag(name = "通知管理", description = "系统通知相关操作")
public class SysNoticeHandler {

    private final ISysNoticeService noticeService;
    private static final List<String> VALID_NOTICE_TYPES = Arrays.asList("1", "2");
    private static final List<String> VALID_STATUSES = Arrays.asList("0", "1");

    public SysNoticeHandler(ISysNoticeService noticeService) {
        this.noticeService = noticeService;
    }

    @Operation(summary = "获取所有通知", description = "获取系统中所有通知列表")
    public Mono<ServerResponse> getAllNotices(ServerRequest request) {
        Flux<SysNotice> notices = noticeService.getAllNotices();
        return ServerResponse.ok().body(notices, SysNotice.class);
    }

    @Operation(summary = "根据ID获取通知", description = "根据通知ID获取通知详细信息")
    public Mono<ServerResponse> getNoticeById(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        return noticeService.getNoticeById(id)
                .flatMap(notice -> ServerResponse.ok().bodyValue(notice))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    @Operation(summary = "根据状态获取通知", description = "根据状态获取通知列表")
    public Mono<ServerResponse> getNoticesByStatus(ServerRequest request) {
        String status = request.pathVariable("status");
        Flux<SysNotice> notices = noticeService.getNoticesByStatus(status);
        return ServerResponse.ok().body(notices, SysNotice.class);
    }

    @Operation(summary = "创建通知", description = "创建新通知")
    public Mono<ServerResponse> createNotice(ServerRequest request) {
        return request.bodyToMono(SysNotice.class)
                .filter(notice -> notice.getNoticeTitle() != null && !notice.getNoticeTitle().trim().isEmpty())
                .switchIfEmpty(Mono.error(new IllegalArgumentException("公告标题不能为空")))
                .filter(notice -> VALID_NOTICE_TYPES.contains(notice.getNoticeType()))
                .switchIfEmpty(Mono.error(new IllegalArgumentException("公告类型必须是1(通知)或2(公告)")))
                .filter(notice -> notice.getNoticeContent() != null && !notice.getNoticeContent().trim().isEmpty())
                .switchIfEmpty(Mono.error(new IllegalArgumentException("公告内容不能为空")))
                .filter(notice -> notice.getStatus() == null || VALID_STATUSES.contains(notice.getStatus()))
                .switchIfEmpty(Mono.error(new IllegalArgumentException("状态必须是0(正常)或1(关闭)")))
                .flatMap(noticeService::createNotice)
                .flatMap(notice -> ServerResponse.created(request.uriBuilder().path("/{id}").build(notice.getId())).bodyValue(notice))
                .onErrorResume(IllegalArgumentException.class, ex -> {
                    return ServerResponse.badRequest().bodyValue(Map.of(
                            "code", HttpStatus.BAD_REQUEST.value(),
                            "message", ex.getMessage(),
                            "timestamp", LocalDateTime.now()
                    ));
                });
    }

    @Operation(summary = "更新通知", description = "更新通知信息")
    public Mono<ServerResponse> updateNotice(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        return request.bodyToMono(SysNotice.class)
                .flatMap(notice -> noticeService.updateNotice(id, notice))
                .flatMap(notice -> ServerResponse.ok().bodyValue(notice))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    @Operation(summary = "删除通知", description = "删除指定通知")
    public Mono<ServerResponse> deleteNotice(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        return noticeService.getNoticeById(id)
                .filter(notice -> notice.getDeletedAt() == null)
                .flatMap(notice -> noticeService.deleteNotice(id)
                        .then(ServerResponse.noContent().build()))
                .switchIfEmpty(ServerResponse.notFound().build());
    }
}