<?php

namespace App\Http\Controllers;

use App\Models\FcmSendLog;
use App\Models\PushDeviceToken;
use App\Models\Tenants\Tenant;
use App\Services\FcmApiService;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;

// Note: Response is still used by deleteToken() method

class FcmController extends Controller
{
    public function __construct(
        private readonly FcmApiService $fcmApiService
    ) {}

    /**
     * FCM 토큰 관리 페이지
     */
    public function tokens(Request $request): View
    {
        $tenants = Tenant::orderBy('company_name')->get();
        $tokens = $this->getTokensQuery($request)->paginate(20);
        $stats = $this->getTokenStats($request->get('tenant_id'));

        return view('fcm.tokens', compact('tenants', 'tokens', 'stats'));
    }

    /**
     * FCM 토큰 목록 (HTMX partial)
     */
    public function tokenList(Request $request): View
    {
        $tokens = $this->getTokensQuery($request)->paginate(20);

        return view('fcm.partials.token-table', compact('tokens'));
    }

    /**
     * 토큰 통계 (HTMX partial)
     */
    public function tokenStats(Request $request): View
    {
        $stats = $this->getTokenStats($request->get('tenant_id'));

        return view('fcm.partials.token-stats', compact('stats'));
    }

    /**
     * 토큰 상태 변경 (활성/비활성)
     */
    public function toggleToken(Request $request, int $id): View
    {
        $token = PushDeviceToken::withoutGlobalScopes()->findOrFail($id);

        $token->update([
            'is_active' => ! $token->is_active,
        ]);

        return view('fcm.partials.token-row', compact('token'));
    }

    /**
     * 토큰 삭제
     */
    public function deleteToken(int $id): Response
    {
        $token = PushDeviceToken::withoutGlobalScopes()->findOrFail($id);
        $token->delete();

        return response('', 200)
            ->header('HX-Trigger', 'tokenDeleted');
    }

    /**
     * 에러 토큰 전체 삭제
     */
    public function deleteErrorTokens(Request $request): Response
    {
        $query = PushDeviceToken::withoutGlobalScopes()->whereNotNull('last_error');

        if ($tenantId = $request->get('tenant_id')) {
            $query->where('tenant_id', $tenantId);
        }

        $count = $query->count();
        $query->toBase()->delete();

        \Log::info("에러 토큰 전체삭제: {$count}건 영구 삭제");

        return response('', 200)
            ->header('HX-Refresh', 'true');
    }

    /**
     * FCM 테스트 발송 페이지
     */
    public function send(): View
    {
        $tenants = Tenant::orderBy('company_name')->get();

        return view('fcm.send', compact('tenants'));
    }

    /**
     * FCM 발송 실행 (HTMX)
     *
     * API 서버를 통해 FCM을 발송합니다.
     */
    public function sendPush(Request $request): View
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'body' => 'required|string|max:1000',
            'tenant_id' => 'nullable|integer|exists:tenants,id',
            'user_id' => 'nullable|integer',
            'platform' => 'nullable|string|in:android,ios,web',
            'channel_id' => 'nullable|string|in:push_default,push_vendor_register,push_approval_request,push_income,push_sales_order,push_purchase_order,push_contract',
            'type' => 'nullable|string|max:50',
            'url' => 'nullable|string|max:500',
        ]);

        // API 서버로 발송 요청
        $result = $this->fcmApiService->send(
            array_filter([
                'title' => $request->get('title'),
                'body' => $request->get('body'),
                'tenant_id' => $request->get('tenant_id'),
                'user_id' => $request->get('user_id'),
                'platform' => $request->get('platform'),
                'channel_id' => $request->get('channel_id', 'push_default'),
                'type' => $request->get('type'),
                'url' => $request->get('url'),
            ]),
            auth()->id()
        );

        if (! $result['success']) {
            return view('fcm.partials.send-result', [
                'success' => false,
                'message' => $result['message'] ?? 'FCM 발송에 실패했습니다.',
            ]);
        }

        return view('fcm.partials.send-result', [
            'success' => true,
            'message' => $result['message'] ?? '발송 완료',
            'data' => $result['data'] ?? [],
        ]);
    }

    /**
     * FCM 발송 이력 페이지
     */
    public function history(Request $request): View
    {
        $logs = $this->getHistoryQuery($request)->paginate(20);

        return view('fcm.history', compact('logs'));
    }

    /**
     * FCM 발송 이력 목록 (HTMX partial)
     */
    public function historyList(Request $request): View
    {
        $logs = $this->getHistoryQuery($request)->paginate(20);

        return view('fcm.partials.history-table', compact('logs'));
    }

    /**
     * 대상 토큰 수 미리보기 (HTMX)
     */
    public function previewCount(Request $request): View
    {
        $query = PushDeviceToken::withoutGlobalScopes()->active();

        if ($tenantId = $request->get('tenant_id')) {
            $query->forTenant($tenantId);
        }

        if ($userId = $request->get('user_id')) {
            $query->forUser($userId);
        }

        if ($platform = $request->get('platform')) {
            $query->platform($platform);
        }

        $count = $query->count();

        return view('fcm.partials.preview-count', compact('count'));
    }

    /**
     * 토큰 쿼리 빌더
     */
    private function getTokensQuery(Request $request)
    {
        $query = PushDeviceToken::withoutGlobalScopes()
            ->with(['user:id,name,email', 'tenant:id,company_name']);

        if ($tenantId = $request->get('tenant_id')) {
            $query->where('tenant_id', $tenantId);
        }

        if ($platform = $request->get('platform')) {
            $query->where('platform', $platform);
        }

        if ($request->has('is_active') && $request->get('is_active') !== '') {
            $query->where('is_active', $request->boolean('is_active'));
        }

        if ($request->boolean('has_error')) {
            $query->hasError();
        }

        if ($search = $request->get('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('token', 'like', "%{$search}%")
                    ->orWhere('device_name', 'like', "%{$search}%")
                    ->orWhereHas('user', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    });
            });
        }

        return $query->orderBy('created_at', 'desc');
    }

    /**
     * 토큰 통계 가져오기
     */
    private function getTokenStats(?int $tenantId = null): array
    {
        $query = PushDeviceToken::withoutGlobalScopes();

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

        $total = (clone $query)->count();
        $active = (clone $query)->where('is_active', true)->count();
        $inactive = (clone $query)->where('is_active', false)->count();
        $hasError = (clone $query)->whereNotNull('last_error')->count();

        $byPlatform = (clone $query)->selectRaw('platform, count(*) as count')
            ->groupBy('platform')
            ->pluck('count', 'platform')
            ->toArray();

        return [
            'total' => $total,
            'active' => $active,
            'inactive' => $inactive,
            'has_error' => $hasError,
            'by_platform' => $byPlatform,
        ];
    }

    /**
     * 발송 이력 쿼리 빌더
     */
    private function getHistoryQuery(Request $request)
    {
        $query = FcmSendLog::with(['sender:id,name', 'tenant:id,company_name']);

        if ($tenantId = $request->get('tenant_id')) {
            $query->where('tenant_id', $tenantId);
        }

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

        if ($from = $request->get('from')) {
            $query->whereDate('created_at', '>=', $from);
        }

        if ($to = $request->get('to')) {
            $query->whereDate('created_at', '<=', $to);
        }

        return $query->orderBy('created_at', 'desc');
    }
}
