package ru.soune.nocopy.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.tarriff.TariffDTO;
import ru.soune.nocopy.dto.tarriff.TariffRequest;
import ru.soune.nocopy.dto.tarriff.TariffResponse;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffTimeTerm;
import ru.soune.nocopy.service.tariff.TariffService;

import java.util.List;

@RequiredArgsConstructor
@Component
@Slf4j
public class TariffInformationHandler implements RequestHandler {

    private final ObjectMapper objectMapper;

    private final TariffService tariffService;

    @Override
    public BaseResponse handle(BaseRequest request) throws Exception {
        try {
            TariffRequest tariffRequest = objectMapper.convertValue(request.getMessageBody(), TariffRequest.class);
            String action = tariffRequest.getAction();

            switch (action) {
                case "get_all" :
                    return handleGetTariffs(request, tariffRequest);
                case "tariffs_by_type" :
                    return handleGetTariffsByType(request, tariffRequest);
            }

        } catch (Exception e) {
            log.error("Error add tariff", e);
            return new BaseResponse(
                    request.getMsgId(),
                    MessageCode.SUCCESS.getCode(),
                    "Error processing request: " + e.getMessage(),
                    null);
        }

        return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
                MessageCode.SUCCESS.getDescription(), null);
    }


    private BaseResponse handleGetTariffsByType(BaseRequest request, TariffRequest req) {
        int page = req.getPage() != null ? req.getPage() : 0;
        int pageSize = req.getSize() != null ? req.getSize() : 5;
        String sortDirection = req.getSortDirection() != null ? req.getSortDirection() : "desc";
        String sortBy = req.getSortBy() != null ? req.getSortBy() : "name";
        Pageable pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.fromString(sortDirection), sortBy));

        Page<Tariff> allTariffs = tariffService.getTariffs(pageable);

        List<TariffDTO> tariffDTOS = allTariffs.stream()
                .map(this::convertToDTO)
                .toList();

        TariffResponse tariffResponse = TariffResponse.builder()
                .tariffs(tariffDTOS)
                .page(page)
                .pageSize(pageSize)
                .sortBy(sortBy)
                .sortDirection(sortDirection)
                .totalElements(allTariffs.getTotalElements())
                .totalPages(allTariffs.getTotalPages())
                .build();

        return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
                MessageCode.SUCCESS.getDescription(), tariffResponse);
    }

    private BaseResponse handleGetTariffs(BaseRequest request, TariffRequest req) {
        int page = req.getPage() != null ? req.getPage() : 0;
        int pageSize = req.getSize() != null ? req.getSize() : 5;
        String sortDirection = req.getSortDirection() != null ? req.getSortDirection() : "desc";
        String sortBy = req.getSortBy() != null ? req.getSortBy() : "name";

        Pageable pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.fromString(sortDirection), sortBy));

        Page<Tariff> allTariffs = tariffService.getTariffs(pageable);

        List<TariffDTO> tariffDTOS = allTariffs.stream()
                .map(this::convertToDTO)
                .toList();

        TariffResponse tariffResponse = TariffResponse.builder()
                .tariffs(tariffDTOS)
                .page(page)
                .pageSize(pageSize)
                .sortBy(sortBy)
                .sortDirection(sortDirection)
                .totalElements(allTariffs.getTotalElements())
                .totalPages(allTariffs.getTotalPages())
                .build();

        return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
                MessageCode.SUCCESS.getDescription(), tariffResponse);
    }

    private TariffDTO convertToDTO(Tariff tariff) {
        TariffTimeTerm tariffTerm = tariff.getTariffTerm();

        return new TariffDTO(
                tariff.getId(),
                tariff.getType(),
                tariff.getName(),
                tariff.getPrice(),
                tariff.getTokens(),
                tariff.getMaxFilesCount(),
                tariff.getDiskSize(),
                tariff.getMaxUsers(),
                tariffTerm == null ? "" : tariffTerm.name(),
                tariff.getDescription() == null ? "" : tariff.getDescription()
        );
    }
}
