package com.writeoff.module.expert.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.writeoff.security.AuthContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class ExpertSnapshotService {
    private final JdbcTemplate jdbcTemplate;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public ExpertSnapshotService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Transactional(rollbackFor = Exception.class)
    public int snapshotOnMeetingSubmit(Long meetingId) {
        List<String> list = jdbcTemplate.queryForList(
                "SELECT content_json FROM meeting_material WHERE tenant_id=? AND meeting_id=? AND module_code='EXPERT_PROFILE' AND is_deleted=0 LIMIT 1",
                String.class,
                tenantId(),
                meetingId
        );
        if (list.isEmpty() || list.get(0) == null || list.get(0).trim().isEmpty()) {
            return 0;
        }
        List<Map<String, Object>> profiles = new java.util.ArrayList<Map<String, Object>>();
        try {
            Map<String, Object> root = objectMapper.readValue(list.get(0), new TypeReference<Map<String, Object>>() {});
            Object profileObj = root.get("profiles");
            if (!(profileObj instanceof List)) {
                return 0;
            }
            List<?> rawProfiles = (List<?>) profileObj;
            for (Object item : rawProfiles) {
                if (item instanceof Map) {
                    Map<String, Object> profile = new LinkedHashMap<String, Object>();
                    Map<?, ?> rawMap = (Map<?, ?>) item;
                    for (Map.Entry<?, ?> entry : rawMap.entrySet()) {
                        profile.put(String.valueOf(entry.getKey()), entry.getValue());
                    }
                    profiles.add(profile);
                }
            }
        } catch (Exception ex) {
            return 0;
        }

        jdbcTemplate.update(
                "DELETE FROM meeting_expert_snapshot WHERE tenant_id=? AND meeting_id=?",
                tenantId(),
                meetingId
        );

        int count = 0;
        for (Map<String, Object> profile : profiles) {
            Long expertId = resolveExpertId(profile);
            if (expertId == null) {
                continue;
            }
            String snapshotJson;
            try {
                Map<String, Object> snapshot = new LinkedHashMap<String, Object>(profile);
                snapshot.put("expertId", expertId);
                snapshotJson = objectMapper.writeValueAsString(snapshot);
            } catch (Exception ex) {
                continue;
            }
            jdbcTemplate.update(
                    "INSERT INTO meeting_expert_snapshot (tenant_id, meeting_id, expert_id, snapshot_json, created_by) VALUES (?, ?, ?, ?, ?)",
                    tenantId(),
                    meetingId,
                    expertId,
                    snapshotJson,
                    safeUserId()
            );
            count++;
        }
        return count;
    }

    private Long resolveExpertId(Map<String, Object> profile) {
        Object rawId = profile.get("expertId");
        if (rawId != null && String.valueOf(rawId).trim().matches("\\d+")) {
            Long expertId = Long.valueOf(String.valueOf(rawId).trim());
            Integer count = jdbcTemplate.queryForObject(
                    "SELECT COUNT(1) FROM expert WHERE tenant_id=? AND id=? AND is_deleted=0",
                    Integer.class,
                    tenantId(),
                    expertId
            );
            if (count != null && count > 0) {
                return expertId;
            }
        }
        String expertName = value(profile.get("expertName"));
        String organization = value(profile.get("organization"));
        if (expertName.isEmpty()) {
            return null;
        }
        List<Long> ids = jdbcTemplate.queryForList(
                "SELECT id FROM expert WHERE tenant_id=? AND expert_name=? AND (?='' OR organization=?) AND is_deleted=0 ORDER BY id DESC LIMIT 1",
                Long.class,
                tenantId(),
                expertName,
                organization,
                organization
        );
        return ids.isEmpty() ? null : ids.get(0);
    }

    private String value(Object val) {
        return val == null ? "" : String.valueOf(val).trim();
    }

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

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