package com.goldenchart.service;

import com.goldenchart.entity.GcFcmToken;
import com.goldenchart.repository.GcFcmTokenRepository;
import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
@Slf4j
public class FcmPushService {

    private final GcFcmTokenRepository tokenRepo;
    private final AppSettingsService appSettingsService;

    @Value("${firebase.enabled:false}")
    private boolean firebaseEnabled;

    @Transactional
    public void registerToken(Long userId, String deviceId, String token) {
        if (token == null || token.isBlank()) return;
        String dev = deviceId != null ? deviceId : "anonymous";
        Optional<GcFcmToken> existing = tokenRepo.findByToken(token);
        if (existing.isPresent()) {
            GcFcmToken t = existing.get();
            t.setUserId(userId);
            t.setDeviceId(dev);
            t.setActive(true);
            t.setLastUsedAt(LocalDateTime.now());
            tokenRepo.save(t);
        } else {
            tokenRepo.save(GcFcmToken.builder()
                    .token(token)
                    .userId(userId)
                    .deviceId(dev)
                    .active(true)
                    .lastUsedAt(LocalDateTime.now())
                    .build());
        }
        log.info("[FCM] token registered device={}", dev);
    }

    @Transactional
    public void deleteByDevice(String deviceId) {
        if (deviceId != null) tokenRepo.deleteByDeviceId(deviceId);
    }

    public boolean isAvailable() {
        return firebaseEnabled && !FirebaseApp.getApps().isEmpty();
    }

    /**
     * 매매 시그널 FCM — deviceId 일치 토큰 + fcm_push_enabled 설정 시.
     */
    public void sendTradeSignalIfEnabled(String deviceId, Long userId, String market,
                                         String signalType, double price,
                                         String strategyName, Long signalId) {
        if (!isAvailable() || deviceId == null) return;
        var app = appSettingsService.getEntity(userId, deviceId);
        if (!Boolean.TRUE.equals(app.getFcmPushEnabled())) return;

        List<GcFcmToken> tokens = tokenRepo.findByDeviceIdAndActiveTrue(deviceId);
        if (tokens.isEmpty()) {
            tokens = tokenRepo.findByActiveTrue();
        }
        if (tokens.isEmpty()) return;

        String title = "BUY".equals(signalType) ? "🟢 매수 시그널" : "🔴 매도 시그널";
        String body = String.format("%s · ₩%,.0f%s",
                market, price,
                strategyName != null ? " · " + strategyName : "");

        for (GcFcmToken t : tokens) {
            try {
                Message msg = Message.builder()
                        .setToken(t.getToken())
                        .setNotification(Notification.builder().setTitle(title).setBody(body).build())
                        .putData("type", "trade_signal")
                        .putData("signalId", signalId != null ? String.valueOf(signalId) : "")
                        .putData("market", market)
                        .putData("signalType", signalType)
                        .putData("price", String.valueOf(price))
                        .build();
                FirebaseMessaging.getInstance().send(msg);
                t.setLastUsedAt(LocalDateTime.now());
                tokenRepo.save(t);
            } catch (FirebaseMessagingException e) {
                log.warn("[FCM] send failed: {}", e.getMessagingErrorCode());
                if (e.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED
                        || e.getMessagingErrorCode() == MessagingErrorCode.INVALID_ARGUMENT) {
                    t.setActive(false);
                    tokenRepo.save(t);
                }
            } catch (Exception e) {
                log.warn("[FCM] send error: {}", e.getMessage());
            }
        }
    }

    public void sendTest(Long userId, String deviceId) {
        if (!isAvailable()) {
            log.warn("[FCM] test skipped — Firebase not initialized");
            return;
        }
        List<GcFcmToken> tokens = deviceId != null
                ? tokenRepo.findByDeviceIdAndActiveTrue(deviceId)
                : tokenRepo.findByActiveTrue();
        for (GcFcmToken t : tokens) {
            try {
                Message msg = Message.builder()
                        .setToken(t.getToken())
                        .setNotification(Notification.builder()
                                .setTitle("GoldenChart 테스트")
                                .setBody("FCM 푸시가 정상 동작합니다.")
                                .build())
                        .putData("type", "test")
                        .build();
                FirebaseMessaging.getInstance().send(msg);
            } catch (Exception e) {
                log.warn("[FCM] test send failed: {}", e.getMessage());
            }
        }
    }
}
