<?php

namespace App\Services\Stats;

use App\Models\Stats\Daily\StatSystemDaily;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class SystemStatService implements StatDomainServiceInterface
{
    public function aggregateDaily(int $tenantId, Carbon $date): int
    {
        $dateStr = $date->format('Y-m-d');

        // API 사용량
        $apiStats = DB::connection('mysql')
            ->table('api_request_logs')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->selectRaw('
                COUNT(*) as request_count,
                SUM(CASE WHEN response_status >= 400 THEN 1 ELSE 0 END) as error_count,
                COALESCE(AVG(duration_ms), 0) as avg_response_ms
            ')
            ->first();

        // 사용자 활동 (고유 사용자 수, 로그인 수)
        $activeUsers = DB::connection('mysql')
            ->table('api_request_logs')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->whereNotNull('user_id')
            ->distinct('user_id')
            ->count('user_id');

        // personal_access_tokens에 tenant_id 없으므로 user_tenants 조인으로 로그인 수 집계
        $loginCount = DB::connection('mysql')
            ->table('personal_access_tokens as pat')
            ->join('user_tenants as ut', function ($join) use ($tenantId) {
                $join->on('pat.tokenable_id', '=', 'ut.user_id')
                    ->where('pat.tokenable_type', '=', 'App\\Models\\Members\\User')
                    ->where('ut.tenant_id', '=', $tenantId);
            })
            ->whereDate('pat.created_at', $dateStr)
            ->count();

        // 감사 로그
        $auditStats = DB::connection('mysql')
            ->table('audit_logs')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->selectRaw("
                SUM(CASE WHEN action = 'created' THEN 1 ELSE 0 END) as create_count,
                SUM(CASE WHEN action = 'updated' THEN 1 ELSE 0 END) as update_count,
                SUM(CASE WHEN action = 'deleted' THEN 1 ELSE 0 END) as delete_count
            ")
            ->first();

        // FCM 알림
        $fcmStats = DB::connection('mysql')
            ->table('fcm_send_logs')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->selectRaw('
                COALESCE(SUM(success_count), 0) as sent_count,
                COALESCE(SUM(failure_count), 0) as failed_count
            ')
            ->first();

        // 파일 업로드
        $fileStats = DB::connection('mysql')
            ->table('files')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->selectRaw('
                COUNT(*) as upload_count,
                COALESCE(SUM(file_size), 0) / 1048576 as upload_size_mb
            ')
            ->first();

        // 결재
        $approvalSubmitted = DB::connection('mysql')
            ->table('approvals')
            ->where('tenant_id', $tenantId)
            ->whereDate('drafted_at', $dateStr)
            ->whereNull('deleted_at')
            ->count();

        $approvalCompleted = DB::connection('mysql')
            ->table('approvals')
            ->where('tenant_id', $tenantId)
            ->whereDate('completed_at', $dateStr)
            ->whereNull('deleted_at')
            ->count();

        $approvalAvgHours = DB::connection('mysql')
            ->table('approvals')
            ->where('tenant_id', $tenantId)
            ->whereDate('completed_at', $dateStr)
            ->whereNotNull('drafted_at')
            ->whereNotNull('completed_at')
            ->whereNull('deleted_at')
            ->selectRaw('AVG(TIMESTAMPDIFF(HOUR, drafted_at, completed_at)) as avg_hours')
            ->value('avg_hours');

        StatSystemDaily::updateOrCreate(
            ['tenant_id' => $tenantId, 'stat_date' => $dateStr],
            [
                'api_request_count' => $apiStats->request_count ?? 0,
                'api_error_count' => $apiStats->error_count ?? 0,
                'api_avg_response_ms' => (int) ($apiStats->avg_response_ms ?? 0),
                'active_user_count' => $activeUsers,
                'login_count' => $loginCount,
                'audit_create_count' => $auditStats->create_count ?? 0,
                'audit_update_count' => $auditStats->update_count ?? 0,
                'audit_delete_count' => $auditStats->delete_count ?? 0,
                'fcm_sent_count' => $fcmStats->sent_count ?? 0,
                'fcm_failed_count' => $fcmStats->failed_count ?? 0,
                'file_upload_count' => $fileStats->upload_count ?? 0,
                'file_upload_size_mb' => $fileStats->upload_size_mb ?? 0,
                'approval_submitted_count' => $approvalSubmitted,
                'approval_completed_count' => $approvalCompleted,
                'approval_avg_hours' => (float) ($approvalAvgHours ?? 0),
            ]
        );

        return 1;
    }

    public function aggregateMonthly(int $tenantId, int $year, int $month): int
    {
        // 시스템 도메인은 일간 테이블만 운영
        return 0;
    }
}
