package com.zioinfo.kintex.admin;

import com.zioinfo.kintex.admin.dto.AdminDashboardDto;
import com.zioinfo.kintex.admin.dto.AdminStatsDto;
import com.zioinfo.kintex.tenant.TenantContext;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 관리자 대시보드 서비스 — 실 테이블 집계로 KPI·라이브 행사를 조립.
 * 관람객 추이는 센서/집계 인프라 부재 → 빈배열. 테넌트는 실 데이터(KINTEX)만 반환.
 */
@Service
public class AdminDashboardService {

    private final AdminDashboardMapper mapper;

    public AdminDashboardService(AdminDashboardMapper mapper) {
        this.mapper = mapper;
    }

    public AdminDashboardDto getDashboard(String tenant) {
        // 집계는 현재 해소된 테넌트로 격리(§8-2). 기준 테넌트('kintex') 단일 운영 시 회귀 0.
        String tenantId = TenantContext.currentTenantId();
        Map<String, Object> c = mapper.findKpiCounts(tenantId);
        long ongoing = lng(c == null ? null : c.get("ongoingEvents"));
        long halls = lng(c == null ? null : c.get("hallsInUse"));
        long users = lng(c == null ? null : c.get("activeUsers"));
        long companies = lng(c == null ? null : c.get("companies"));
        long upcoming = lng(c == null ? null : c.get("upcomingEvents"));

        List<AdminDashboardDto.Kpi> kpis = new ArrayList<>();
        kpis.add(new AdminDashboardDto.Kpi("진행 행사", String.valueOf(ongoing), halls + "개 홀"));
        kpis.add(new AdminDashboardDto.Kpi("예정 행사", String.valueOf(upcoming), null));
        kpis.add(new AdminDashboardDto.Kpi("활성 사용자", String.valueOf(users), null));
        kpis.add(new AdminDashboardDto.Kpi("등록업체", String.valueOf(companies), null));

        List<AdminDashboardDto.LiveEvent> live = new ArrayList<>();
        List<Map<String, Object>> rows = mapper.findLiveEvents(tenantId);
        if (rows != null) {
            for (Map<String, Object> r : rows) {
                long booths = lng(r.get("boothCount"));
                long capacity = lng(r.get("capacity"));
                int occupancy = capacity > 0 ? (int) Math.min(100, Math.round(booths * 100.0 / capacity)) : 0;
                live.add(new AdminDashboardDto.LiveEvent(
                        str(r.get("eventId")), str(r.get("name")), str(r.get("hall")),
                        occupancy, "ongoing"));
            }
        }

        // 관람객 추이: 센서/집계 원천 부재 → 빈배열(정직). 테넌트: 실 데이터 KINTEX 만.
        List<AdminDashboardDto.VisitorPoint> visitorTrend = new ArrayList<>();
        List<String> tenants = List.of("KINTEX");

        return new AdminDashboardDto(kpis, visitorTrend, live, tenants);
    }

    /**
     * 관리자 집계 지표(SCR-16 실전환) — 실 테이블 존재분만 반환. 테넌트 스코프는 대시보드와 동일(§8-2).
     * 실시간 방문객·주차·라이브 IoT 지표는 미포함(M10/M14 이후) — 화면에서 정직한 게이트 유지.
     */
    public AdminStatsDto getStats(String tenant) {
        String tenantId = TenantContext.currentTenantId();
        Map<String, Object> c = mapper.findStatCounts(tenantId);
        return new AdminStatsDto(
                lng(c == null ? null : c.get("totalUsers")),
                lng(c == null ? null : c.get("activeUsers")),
                lng(c == null ? null : c.get("totalEvents")),
                lng(c == null ? null : c.get("ongoingEvents")),
                lng(c == null ? null : c.get("upcomingEvents")),
                lng(c == null ? null : c.get("tenantCount")),
                lng(c == null ? null : c.get("companyCount")),
                lng(c == null ? null : c.get("todayCheckins")));
    }

    private static long lng(Object o) {
        if (o == null) return 0L;
        if (o instanceof Number n) return n.longValue();
        try {
            return Long.parseLong(String.valueOf(o));
        } catch (NumberFormatException e) {
            return 0L;
        }
    }

    private static String str(Object o) {
        return o == null ? null : String.valueOf(o);
    }
}
