<?php

namespace App\Services\ApiExplorer;

use App\Models\DevTools\ApiDeprecation;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

/**
 * API 사용 현황 및 통계 서비스
 */
class ApiUsageService
{
    public function __construct(
        private OpenApiParserService $parser
    ) {}

    /**
     * API 사용 통계 조회
     *
     * @return Collection 엔드포인트별 사용 횟수
     */
    public function getUsageStats(): Collection
    {
        // URL에서 경로만 추출 (도메인 및 쿼리스트링 제거)
        // 예: https://api.sam.kr/api/v1/users?page=1 → /api/v1/users
        // Note: DB facade 사용 (Eloquent accessor 충돌 방지)
        return DB::table('api_request_logs')
            ->selectRaw("REGEXP_REPLACE(SUBSTRING_INDEX(url, '?', 1), '^https?://[^/]+', '') as endpoint")
            ->addSelect('method')
            ->selectRaw('COUNT(*) as call_count')
            ->selectRaw('MAX(created_at) as last_called_at')
            ->selectRaw('AVG(duration_ms) as avg_duration_ms')
            ->selectRaw('SUM(CASE WHEN response_status >= 200 AND response_status < 300 THEN 1 ELSE 0 END) as success_count')
            ->selectRaw('SUM(CASE WHEN response_status >= 400 THEN 1 ELSE 0 END) as error_count')
            ->groupByRaw("REGEXP_REPLACE(SUBSTRING_INDEX(url, '?', 1), '^https?://[^/]+', ''), method")
            ->orderByDesc('call_count')
            ->get();
    }

    /**
     * 전체 API 목록과 사용 현황 비교
     *
     * @return array ['used' => [...], 'unused' => [...], 'stats' => [...]]
     */
    public function getApiUsageComparison(): array
    {
        // Swagger에서 전체 API 목록 조회
        $allEndpoints = $this->parser->getEndpoints();

        // 사용된 API 통계
        $usageStats = $this->getUsageStats()->keyBy(function ($item) {
            return $item->endpoint.'|'.$item->method;
        });

        // 폐기 후보 목록
        $deprecations = ApiDeprecation::active()
            ->get()
            ->keyBy(function ($item) {
                return $item->endpoint.'|'.$item->method;
            });

        $used = [];
        $unused = [];

        foreach ($allEndpoints as $endpoint) {
            $key = $endpoint['path'].'|'.$endpoint['method'];
            $stats = $usageStats->get($key);
            $deprecation = $deprecations->get($key);

            $item = [
                'endpoint' => $endpoint['path'],
                'method' => $endpoint['method'],
                'summary' => $endpoint['summary'] ?? '',
                'tags' => $endpoint['tags'] ?? [],
                'call_count' => $stats->call_count ?? 0,
                'last_called_at' => $stats->last_called_at ?? null,
                'avg_duration_ms' => $stats->avg_duration_ms ?? null,
                'success_count' => $stats->success_count ?? 0,
                'error_count' => $stats->error_count ?? 0,
                'deprecation' => $deprecation,
            ];

            if ($stats) {
                $used[] = $item;
            } else {
                $unused[] = $item;
            }
        }

        // 사용된 API는 호출 횟수 순으로 정렬
        usort($used, fn ($a, $b) => $b['call_count'] <=> $a['call_count']);

        return [
            'used' => $used,
            'unused' => $unused,
            'summary' => [
                'total' => count($allEndpoints),
                'used_count' => count($used),
                'unused_count' => count($unused),
                'deprecation_count' => $deprecations->count(),
            ],
        ];
    }

    /**
     * 미사용 API 목록 조회
     */
    public function getUnusedApis(): Collection
    {
        $comparison = $this->getApiUsageComparison();

        return collect($comparison['unused']);
    }

    /**
     * 폐기 후보 추가
     */
    public function addDeprecationCandidate(
        string $endpoint,
        string $method,
        ?string $reason = null,
        ?int $userId = null
    ): ApiDeprecation {
        return ApiDeprecation::updateOrCreate(
            ['endpoint' => $endpoint, 'method' => strtoupper($method)],
            [
                'status' => ApiDeprecation::STATUS_CANDIDATE,
                'reason' => $reason,
                'created_by' => $userId,
            ]
        );
    }

    /**
     * 폐기 후보 일괄 추가 (미사용 API 전체)
     */
    public function addAllUnusedAsCandidate(?int $userId = null): int
    {
        $unused = $this->getUnusedApis();
        $count = 0;

        foreach ($unused as $api) {
            // 이미 등록되지 않은 것만 추가
            $exists = ApiDeprecation::where('endpoint', $api['endpoint'])
                ->where('method', $api['method'])
                ->exists();

            if (! $exists) {
                $this->addDeprecationCandidate(
                    $api['endpoint'],
                    $api['method'],
                    '미사용 API (자동 등록)',
                    $userId
                );
                $count++;
            }
        }

        return $count;
    }

    /**
     * 폐기 상태 변경
     */
    public function updateDeprecationStatus(
        int $id,
        string $status,
        ?string $reason = null,
        ?\DateTime $scheduledDate = null
    ): ApiDeprecation {
        $deprecation = ApiDeprecation::findOrFail($id);

        $data = ['status' => $status];

        if ($reason !== null) {
            $data['reason'] = $reason;
        }

        if ($scheduledDate !== null) {
            $data['scheduled_date'] = $scheduledDate;
        }

        if ($status === ApiDeprecation::STATUS_DEPRECATED) {
            $data['deprecated_date'] = now();
        }

        $deprecation->update($data);

        return $deprecation->fresh();
    }

    /**
     * 폐기 후보 삭제
     */
    public function removeDeprecation(int $id): void
    {
        ApiDeprecation::where('id', $id)->delete();
    }

    /**
     * 폐기 후보 목록 조회
     */
    public function getDeprecations(?string $status = null): Collection
    {
        $query = ApiDeprecation::with('creator')
            ->orderByDesc('created_at');

        if ($status) {
            $query->where('status', $status);
        }

        return $query->get();
    }

    /**
     * 인기 API 조회 (상위 N개)
     */
    public function getPopularApis(int $limit = 20): Collection
    {
        return $this->getUsageStats()->take($limit);
    }

    /**
     * 최근 사용되지 않은 API (N일 이상)
     */
    public function getStaleApis(int $days = 30): Collection
    {
        $cutoffDate = now()->subDays($days);

        // 최근 호출된 API (DB facade 사용 - Eloquent accessor 충돌 방지)
        $recentlyUsed = DB::table('api_request_logs')
            ->selectRaw("REGEXP_REPLACE(SUBSTRING_INDEX(url, '?', 1), '^https?://[^/]+', '') as endpoint")
            ->addSelect('method')
            ->where('created_at', '>=', $cutoffDate)
            ->distinct()
            ->get()
            ->map(fn ($item) => $item->endpoint.'|'.$item->method)
            ->toArray();

        // 전체 사용 통계에서 최근 사용된 것 제외
        return $this->getUsageStats()
            ->filter(function ($item) use ($recentlyUsed) {
                $key = $item->endpoint.'|'.$item->method;

                return ! in_array($key, $recentlyUsed);
            });
    }

    /**
     * 일별 API 호출 추이
     */
    public function getDailyTrend(int $days = 30): Collection
    {
        return DB::table('api_request_logs')
            ->select(DB::raw('DATE(created_at) as date'))
            ->selectRaw('COUNT(*) as call_count')
            ->selectRaw("COUNT(DISTINCT CONCAT(REGEXP_REPLACE(SUBSTRING_INDEX(url, '?', 1), '^https?://[^/]+', ''), '|', method)) as unique_endpoints")
            ->where('created_at', '>=', now()->subDays($days))
            ->groupBy('date')
            ->orderBy('date')
            ->get();
    }
}
