package ru.kayashov.bar.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
import ru.kayashov.bar.controller.dto.bar.CategoryResponseDto;
import ru.kayashov.bar.controller.dto.bar.GlassResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.SessionResponseDto;
import ru.kayashov.bar.controller.dto.bar.TagResponseDto;
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.BarResident;
import ru.kayashov.bar.model.entity.SessionEntity;
import ru.kayashov.bar.model.entity.Unit;
import ru.kayashov.bar.model.entity.UnitRepository;
import ru.kayashov.bar.model.entity.UserRole;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.SessionRepository;
import ru.kayashov.bar.repository.TagRepository;
import ru.kayashov.bar.service.SessionService;
import ru.kayashov.bar.service.VisitorService;

import java.util.List;

@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/bar/")
@RequiredArgsConstructor
public class BarController {

    private final SessionService sessionService;
    private final TagRepository tagRepository;
    private final SessionRepository sessionRepository;
    private final VisitorService visitorService;
    private final UnitRepository unitRepository;

    @GetMapping("/list")
    public List<BarResponseDto> getBarList(@RequestParam Boolean my) {
        return sessionService.getBarList(my);
    }

    @GetMapping("/units")
    public List<Unit> getUnitList() {
        return unitRepository.findAll();
    }

    @PostMapping("/addToMyList")
    public void addToMyList(@RequestBody BarResponseDto dto) {
        sessionService.addToMyList(dto);
    }

    @PatchMapping("/enter")
    public void enterChange(@RequestParam Long id, @RequestParam Boolean value) {
        sessionService.enterChange(id, value);
    }

    @GetMapping("tags")
    public List<TagResponseDto> getTags() {
        return tagRepository.findAll()
                .stream()
                .map(TagResponseDto::mapToDto)
                .toList();
    }

    @GetMapping("glass")
    public List<GlassResponseDto> getGlass() {
        return sessionService.getGlassList().stream()
                .map(GlassResponseDto::mapToDto)
                .toList();
    }

    @GetMapping("category")
    public List<CategoryResponseDto> getCategory() {
        return sessionService.getCategoryList().stream()
                .map(CategoryResponseDto::mapToDto)
                .toList();
    }

    @GetMapping("receipt")
    public List<ReceiptResponseDto> getReceipt(@RequestParam("id") Long id) {
        return sessionService.getReceiptList(id);
    }

    @GetMapping("session")
    public Long getSession() {
        return sessionService.findActiveSession().getId();
    }

    @GetMapping("session/info")
    public SessionResponseDto getSessionInfo() {
        SessionEntity session = sessionService.findActiveSession();
        return SessionResponseDto.mapToDto(session);
    }

    @PostMapping("session")
    public void changeSessionStatus(@RequestParam Boolean value) {
        if (value) {
            sessionService.createEmptySession();
            return;
        }
        SessionEntity session = sessionService.findActiveSession();
        session.setIsActive(false);
        sessionRepository.save(session);
    }

    @GetMapping("/getMe")
    public VisitorResponseDto getMe() {
        Visitor visitor = visitorService.getCurrentVisitor();
        BarResident resident = visitor.getResidents().stream().filter(BarResident::getActive).findFirst().orElse(null);
        String role;
        Boolean invited;
        boolean active;
        if(resident != null) {
            role = resident.getRole().toString();
            invited = resident.getInvited();
            active = resident.getBar().getSessions().stream().anyMatch(SessionEntity::getIsActive);
        } else {
            role = UserRole.USER.toString();
            invited = false;
            active = false;
        }
        VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, invited, role, active);
        log.info("Запрос информации о пользователе: {}-{} {}, {}вошел в бар{},в роли {}",
                dto.getId(),
                dto.getName().strip(),
                dto.getLastName() != null ? dto.getLastName().strip() : "",
                invited ? "" : "не ",
                resident != null ? " " + resident.getBar().getId() + "-" + resident.getBar().getName() : "",
                role);
        return dto;
    }
}
