<?php

namespace App\Services\Stats;

use App\Models\Stats\StatAlert;
use App\Services\SlackNotificationService;
use Illuminate\Support\Facades\Log;

class StatMonitorService
{
    /**
     * 집계 실패 알림 기록
     */
    public function recordAggregationFailure(int $tenantId, string $domain, string $jobType, string $errorMessage): void
    {
        try {
            StatAlert::create([
                'tenant_id' => $tenantId,
                'alert_type' => 'aggregation_failure',
                'domain' => $domain,
                'severity' => 'critical',
                'title' => "[{$jobType}] 집계 실패",
                'message' => mb_substr($errorMessage, 0, 500),
                'current_value' => 0,
                'threshold_value' => 0,
                'is_read' => false,
                'is_resolved' => false,
                'created_at' => now(),
            ]);

            // critical 알림 Slack 전송
            app(SlackNotificationService::class)->sendStatAlert(
                "[{$jobType}] 집계 실패",
                mb_substr($errorMessage, 0, 300),
                $domain
            );
        } catch (\Throwable $e) {
            Log::error('stat_alert 기록 실패', [
                'tenant_id' => $tenantId,
                'domain' => $domain,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 데이터 누락 알림 (특정 날짜에 통계 데이터 없음)
     */
    public function recordMissingData(int $tenantId, string $domain, string $date): void
    {
        try {
            // 동일 알림 중복 방지
            $exists = StatAlert::where('tenant_id', $tenantId)
                ->where('alert_type', 'missing_data')
                ->where('domain', $domain)
                ->where('title', 'LIKE', "%{$date}%")
                ->where('is_resolved', false)
                ->exists();

            if ($exists) {
                return;
            }

            StatAlert::create([
                'tenant_id' => $tenantId,
                'alert_type' => 'missing_data',
                'domain' => $domain,
                'severity' => 'warning',
                'title' => "[{$domain}] {$date} 데이터 누락",
                'message' => "{$date} 날짜의 {$domain} 통계 데이터가 없습니다. stat:backfill 실행을 권장합니다.",
                'current_value' => 0,
                'threshold_value' => 1,
                'is_read' => false,
                'is_resolved' => false,
                'created_at' => now(),
            ]);
        } catch (\Throwable $e) {
            Log::error('stat_alert 기록 실패 (missing_data)', [
                'tenant_id' => $tenantId,
                'domain' => $domain,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 정합성 불일치 알림
     */
    public function recordMismatch(int $tenantId, string $domain, string $label, float|int $expected, float|int $actual): void
    {
        try {
            StatAlert::create([
                'tenant_id' => $tenantId,
                'alert_type' => 'data_mismatch',
                'domain' => $domain,
                'severity' => 'critical',
                'title' => "[{$domain}] {$label} 정합성 불일치",
                'message' => "원본={$expected}, 통계={$actual}, 차이=".($actual - $expected),
                'current_value' => $actual,
                'threshold_value' => $expected,
                'is_read' => false,
                'is_resolved' => false,
                'created_at' => now(),
            ]);

            // critical 알림 Slack 전송
            app(SlackNotificationService::class)->sendStatAlert(
                "[{$label}] 정합성 불일치",
                "원본={$expected}, 통계={$actual}, 차이=" . ($actual - $expected),
                $domain
            );
        } catch (\Throwable $e) {
            Log::error('stat_alert 기록 실패 (mismatch)', [
                'tenant_id' => $tenantId,
                'domain' => $domain,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 백업 실패 알림 기록 (시스템 레벨, tenantId=0)
     */
    public function recordBackupFailure(string $title, string $message): void
    {
        try {
            StatAlert::create([
                'tenant_id' => 0,
                'alert_type' => 'backup_failure',
                'domain' => 'backup',
                'severity' => 'critical',
                'title' => $title,
                'message' => mb_substr($message, 0, 500),
                'current_value' => 0,
                'threshold_value' => 0,
                'is_read' => false,
                'is_resolved' => false,
                'created_at' => now(),
            ]);
        } catch (\Throwable $e) {
            Log::error('stat_alert 기록 실패 (backup_failure)', [
                'title' => $title,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 알림 해결 처리
     */
    public function resolveAlerts(int $tenantId, string $domain, string $alertType): int
    {
        return StatAlert::where('tenant_id', $tenantId)
            ->where('domain', $domain)
            ->where('alert_type', $alertType)
            ->where('is_resolved', false)
            ->update([
                'is_resolved' => true,
                'resolved_at' => now(),
            ]);
    }
}
