<?php

namespace App\Http\Controllers;

use Google\Auth\Credentials\ServiceAccountCredentials;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class NotificationController extends Controller
{
    public function send(Request $request)
    {
        $data = $request->validate([
            'tokens' => ['required', 'array', 'min:1'],
            'tokens.*' => ['string'],
            'title' => ['required', 'string'],
            'msg' => ['required', 'string'],
            'img' => ['nullable', 'string'],
        ]);

        $projectId = (string) (config('services.fcm.v1_project_id') ?? '');
        $serverKey = (string) (config('services.fcm.server_key') ?? '');

        if (filled($projectId)) {
            return $this->sendViaHttpV1($projectId, $data);
        }

        if (empty($serverKey)) {
            return response()->json([
                'ok' => false,
                'error' => 'FCM server key no configurada',
            ], 500);
        }

        $payload = [
            'registration_ids' => $data['tokens'],
            'notification' => [
                'title' => $data['title'],
                'body' => $data['msg'],
            ],
            'data' => [
                'title' => $data['title'],
                'message' => $data['msg'],
            ],
            'priority' => 'high',
            'content_available' => true,
        ];

        if (filled($data['img'])) {
            $payload['notification']['image'] = $data['img'];
            $payload['data']['image'] = $data['img'];
        }

        try {
            $response = Http::withHeaders([
                'Authorization' => "key={$serverKey}",
                'Content-Type' => 'application/json',
            ])->post('https://fcm.googleapis.com/fcm/send', $payload);
        } catch (\Throwable $e) {
            return response()->json([
                'ok' => false,
                'status' => 0,
                'error' => $e->getMessage(),
            ], 500);
        }

        if ($response->failed()) {
            return response()->json([
                'ok' => false,
                'status' => $response->status(),
                'error' => $response->json()['error'] ?? $response->body(),
                'fcm' => $response->json() ?? null,
            ], 500);
        }

        $fcm = $response->json();
        $errors = [];
        if (is_array($fcm) && isset($fcm['results']) && is_array($fcm['results'])) {
            foreach ($fcm['results'] as $i => $res) {
                if (isset($res['error'])) {
                    $errors[] = [
                        'token' => $data['tokens'][$i] ?? null,
                        'error' => $res['error'],
                    ];
                }
            }
        }

        return response()->json([
            'ok' => true,
            'summary' => [
                'success' => $fcm['success'] ?? 0,
                'failure' => $fcm['failure'] ?? 0,
            ],
            'errors' => $errors,
            'fcm' => $fcm,
        ]);
    }

    protected function sendViaHttpV1(string $projectId, array $data)
    {
        $credentialsPath = (string) (env('GOOGLE_APPLICATION_CREDENTIALS') ?? '');
        if (empty($credentialsPath) || ! file_exists($credentialsPath)) {
            return response()->json([
                'ok' => false,
                'error' => 'Ruta de credenciales de servicio inválida. Configure GOOGLE_APPLICATION_CREDENTIALS.',
            ], 500);
        }

        try {
            $creds = new ServiceAccountCredentials(
                ['https://www.googleapis.com/auth/firebase.messaging'],
                json_decode((string) file_get_contents($credentialsPath), true)
            );
            $tokenData = $creds->fetchAuthToken();
            $accessToken = $tokenData['access_token'] ?? null;
        } catch (\Throwable $e) {
            return response()->json([
                'ok' => false,
                'error' => 'No se pudo obtener token OAuth para FCM v1: '.$e->getMessage(),
            ], 500);
        }

        if (empty($accessToken)) {
            return response()->json([
                'ok' => false,
                'error' => 'Token de acceso vacío para FCM v1',
            ], 500);
        }

        $endpoint = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send";

        $results = [];
        $success = 0;
        $failure = 0;

        foreach ($data['tokens'] as $i => $token) {
            $message = [
                'message' => [
                    'token' => $token,
                    'notification' => [
                        'title' => $data['title'],
                        'body' => $data['msg'],
                    ],
                    'data' => [
                        'title' => $data['title'],
                        'message' => $data['msg'],
                    ],
                ],
            ];

            if (filled($data['img'])) {
                $message['message']['notification']['image'] = $data['img'];
                $message['message']['data']['image'] = $data['img'];
            }

            try {
                $resp = Http::withToken($accessToken)
                    ->withHeader('Content-Type', 'application/json')
                    ->post($endpoint, $message);
            } catch (\Throwable $e) {
                $failure++;
                $results[] = [
                    'token' => $token,
                    'error' => $e->getMessage(),
                ];

                continue;
            }

            if ($resp->failed()) {
                $failure++;
                $payload = $resp->json();
                $results[] = [
                    'token' => $token,
                    'status' => $resp->status(),
                    'error' => $payload['error']['message'] ?? $resp->body(),
                    'detail' => $payload ?? null,
                ];
            } else {
                $success++;
                $payload = $resp->json();
                $results[] = [
                    'token' => $token,
                    'name' => $payload['name'] ?? null,
                ];
            }
        }

        return response()->json([
            'ok' => $failure === 0,
            'summary' => [
                'success' => $success,
                'failure' => $failure,
            ],
            'results' => $results,
        ]);
    }
}
