package com.tasteby.service;

import com.tasteby.domain.Memo;
import com.tasteby.mapper.MemoMapper;
import com.tasteby.util.IdGenerator;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
public class MemoService {

    private final MemoMapper mapper;

    public MemoService(MemoMapper mapper) {
        this.mapper = mapper;
    }

    public Memo findByUserAndRestaurant(String userId, String restaurantId) {
        return mapper.findByUserAndRestaurant(userId, restaurantId);
    }

    @Transactional
    public Memo upsert(String userId, String restaurantId, Double rating, String memoText, LocalDate visitedAt) {
        String visitedStr = visitedAt != null ? visitedAt.toString() : null;
        // #294 — 동시성 가드: 사전 SELECT → 분기 INSERT/UPDATE 패턴은 두 트랜잭션이 동시에 미존재
        // 판정 후 둘 다 INSERT → UNIQUE 충돌(500). INSERT 우선 시도 후 DuplicateKeyException 시 UPDATE.
        Memo existing = mapper.findByUserAndRestaurant(userId, restaurantId);
        if (existing != null) {
            mapper.updateMemo(userId, restaurantId, rating, memoText, visitedStr);
        } else {
            try {
                mapper.insertMemo(IdGenerator.newId(), userId, restaurantId, rating, memoText, visitedStr);
            } catch (DuplicateKeyException e) {
                // 동시 INSERT 충돌 → UPDATE로 폴백
                mapper.updateMemo(userId, restaurantId, rating, memoText, visitedStr);
            }
        }
        return mapper.findByUserAndRestaurant(userId, restaurantId);
    }

    public boolean delete(String userId, String restaurantId) {
        return mapper.deleteMemo(userId, restaurantId) > 0;
    }

    public List<Memo> findByUser(String userId) {
        return mapper.findByUser(userId);
    }
}
