package com.writeoff.module.notification.provider;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.writeoff.module.notification.ws.NotificationWebSocketPushService;
import com.writeoff.security.AuthContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class InAppNotificationProvider implements NotificationChannelProvider {
    private final JdbcTemplate jdbcTemplate;
    private final NotificationWebSocketPushService webSocketPushService;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public InAppNotificationProvider(JdbcTemplate jdbcTemplate, NotificationWebSocketPushService webSocketPushService) {
        this.jdbcTemplate = jdbcTemplate;
        this.webSocketPushService = webSocketPushService;
    }

    @Override
    public String channel() {
        return "IN_APP";
    }

    @Override
    public NotificationSendResult send(String receiverRef, String payloadJson, Map<String, Object> context) {
        if (receiverRef == null || receiverRef.trim().isEmpty()) {
            return new NotificationSendResult(false, null, "INVALID_RECEIVER", "站内通知接收人不能为空");
        }
        String normalizedReceiver = receiverRef.trim();
        String title = "系统通知";
        String content = payloadJson == null ? "" : payloadJson;
        Long receiverUserId = parseReceiverUserId(normalizedReceiver);
        try {
            if (payloadJson != null && payloadJson.trim().startsWith("{")) {
                Map<String, Object> payload = objectMapper.readValue(payloadJson, new TypeReference<Map<String, Object>>() {});
                Object titleVal = payload.get("title");
                if (titleVal == null) {
                    titleVal = payload.get("subject");
                }
                Object contentVal = payload.get("content");
                if (contentVal == null) {
                    contentVal = payload.get("message");
                }
                if (titleVal != null && String.valueOf(titleVal).trim().length() > 0) {
                    title = String.valueOf(titleVal).trim();
                }
                if (contentVal != null) {
                    content = String.valueOf(contentVal);
                }
            }
            Map<String, Object> payload = new LinkedHashMap<String, Object>();
            if (payloadJson != null && payloadJson.trim().startsWith("{")) {
                payload = objectMapper.readValue(payloadJson, new TypeReference<Map<String, Object>>() {});
            }
            if (context != null) {
                payload.putAll(context);
            }
            String mergedPayloadJson = payloadJson;
            if (!payload.isEmpty()) {
                mergedPayloadJson = objectMapper.writeValueAsString(payload);
            }
            jdbcTemplate.update(
                    "INSERT INTO in_app_notification (tenant_id, receiver_ref, receiver_user_id, title, content, payload_json, status, created_by, updated_by) " +
                            "VALUES (?, ?, ?, ?, ?, ?, 'UNREAD', ?, ?)",
                    tenantId(),
                    normalizedReceiver,
                    receiverUserId,
                    title,
                    content,
                    mergedPayloadJson,
                    safeUserId(),
                    safeUserId()
            );
            webSocketPushService.pushInAppNotification(tenantId(), normalizedReceiver, receiverUserId);
            String id = "INAPP-" + System.currentTimeMillis();
            return new NotificationSendResult(true, id, "SENT", "站内通知已送达");
        } catch (Exception ex) {
            return new NotificationSendResult(false, null, "SEND_FAILED", ex.getMessage());
        }
    }

    private Long parseReceiverUserId(String receiverRef) {
        if (receiverRef == null) {
            return null;
        }
        String val = receiverRef.trim();
        if (val.length() == 0) {
            return null;
        }
        if (val.startsWith("user-")) {
            String idPart = val.substring("user-".length());
            try {
                return Long.valueOf(idPart);
            } catch (Exception ex) {
                return null;
            }
        }
        try {
            return Long.valueOf(val);
        } catch (Exception ex) {
            return null;
        }
    }

    private Long safeUserId() {
        Long userId = AuthContext.userId();
        return userId == null ? 0L : userId;
    }

    private Long tenantId() {
        return AuthContext.requireTenantId();
    }
}
