package com.unicorn.hgzero.meeting.infra.gateway;

import com.unicorn.hgzero.meeting.biz.domain.Todo;
import com.unicorn.hgzero.meeting.biz.usecase.out.TodoReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.TodoWriter;
import com.unicorn.hgzero.meeting.infra.gateway.entity.TodoEntity;
import com.unicorn.hgzero.meeting.infra.gateway.repository.TodoJpaRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Todo Gateway 구현체
 * TodoReader, TodoWriter 인터페이스 구현
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TodoGateway implements TodoReader, TodoWriter {

    private final TodoJpaRepository todoJpaRepository;

    @Override
    public Optional<Todo> findById(String todoId) {
        return todoJpaRepository.findById(todoId)
                .map(TodoEntity::toDomain);
    }

    @Override
    public List<Todo> findByMeetingId(String meetingId) {
        return todoJpaRepository.findByMeetingId(meetingId).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByMinutesId(String minutesId) {
        return todoJpaRepository.findByMinutesId(minutesId).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByAssigneeId(String assigneeId) {
        return todoJpaRepository.findByAssigneeId(assigneeId).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByStatus(String status) {
        return todoJpaRepository.findByStatus(status).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByAssigneeIdAndStatus(String assigneeId, String status) {
        return todoJpaRepository.findByAssigneeIdAndStatus(assigneeId, status).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByDueDate(LocalDate dueDate) {
        return todoJpaRepository.findByDueDate(dueDate).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByDueDateBefore(LocalDate date) {
        return todoJpaRepository.findByDueDateBefore(date).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByPriority(String priority) {
        return todoJpaRepository.findByPriority(priority).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<Todo> findByAssigneeIdAndDueDateBetween(String assigneeId, LocalDate startDate, LocalDate endDate) {
        return todoJpaRepository.findByAssigneeIdAndDueDateBetween(assigneeId, startDate, endDate).stream()
                .map(TodoEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public Todo save(Todo todo) {
        TodoEntity entity = TodoEntity.fromDomain(todo);
        TodoEntity savedEntity = todoJpaRepository.save(entity);
        return savedEntity.toDomain();
    }

    @Override
    public void delete(String todoId) {
        todoJpaRepository.deleteById(todoId);
    }
}
