<?php

namespace App\Services;

use App\DTOs\Stripe\CreateCustomerDTO;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Stripe\Stripe;
use Illuminate\Http\Response;
use Stripe\Exception\ApiErrorException;
use Exception;
use Stripe\PaymentMethod;

class StripeService
{
    public function __construct()
    {
        Stripe::setApiKey(config('app.stripe.secret'));
    }

    public function createCustomer(CreateCustomerDTO $dtoCustomer): JsonResponse
    {
        try {
            $user = User::find($dtoCustomer->user_id);
            if (!$user) {
                return response()->json(['error' => "No encontramos tus datos, lo sentimos."], 500);
            }
            if ($user->stripe_customer_id) {
                return response()->json([
                    'message' => 'Gracias por esperar. Ya puedes agregar tu tarjeta.',
                    'customer_id' => $user->stripe_customer_id
                ], Response::HTTP_OK);
            }
            $customerNew = \Stripe\Customer::create([
                'email' => $dtoCustomer->email,
                'name' => $dtoCustomer->name,
                'metadata' => ['user_id' => $dtoCustomer->user_id]
            ]);
            if (!$customerNew->id) {
                return response()->json(['error' => "Lo sentimos estamos teniendo dificultades tecnicas."], 500);
            }
            $user = User::find($dtoCustomer->user_id);
            $user->stripe_customer_id = $customerNew->id;
            $user->save();
            return response()->json([
                'message' => "Gracias por esperar. Ya puedes agregar tu tarjeta.",
                'customer_id' => $customerNew->id
            ], Response::HTTP_OK);
        } catch (ApiErrorException $e) {
            return response()->json(['error' => "Error al guardar el método de pago."], 500);
        } catch (Exception $e) {
            return response()->json(['error' => "Error al guardar"], 500);
        }
    }

    public function createSetupIntent(int $userId): JsonResponse
    {
        try {
            $user = User::find($userId);
            if (!$user || !$user->stripe_customer_id) {
                return response()->json(['error' => 'No se encontró el cliente de Stripe.'], 500);
            }
            $setupIntent = \Stripe\SetupIntent::create([
                'customer' => $user->stripe_customer_id,
                'payment_method_types' => ['card'],
            ]);
            return response()->json([
                'clientSecret' => $setupIntent->client_secret,
            ], Response::HTTP_OK);
        } catch (ApiErrorException $e) {
            return response()->json(['error' => 'Error con Stripe: ' . $e->getMessage()], 500);
        } catch (Exception $e) {
            return response()->json(['error' => 'Error inesperado: ' . $e->getMessage()], 500);
        }
    }

    public function getPaymentMethods(string $stripe_customer_id): JsonResponse
    {
        try {
            $customer = \Stripe\Customer::retrieve($stripe_customer_id);
            if (!$customer) {
                return response()->json(['error' => 'Cliente no encontrado.'], 500);
            }
            $defaultPaymentMethodId = $customer->invoice_settings->default_payment_method;
            $paymentMethods = \Stripe\PaymentMethod::all([
                'customer' => $stripe_customer_id,
                'type' => 'card',
            ]);
            $methodsWithDefault = collect($paymentMethods->data)->map(function ($method) use ($defaultPaymentMethodId) {
                return [
                    'id' => $method->id,
                    'card' => $method->card,
                    'billing_details' => $method->billing_details,
                    'is_default' => $method->id === $defaultPaymentMethodId,
                ];
            });
            return response()->json([
                'methods' => $methodsWithDefault,
            ], Response::HTTP_OK);
        } catch (\Stripe\Exception\ApiErrorException $e) {
            return response()->json(['error' => 'Error con Stripe: ' . $e->getMessage()], 500);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Error inesperado: ' . $e->getMessage()], 500);
        }
    }

    public function detachPaymentMethod(string $payment_method_id): JsonResponse
    {
        try {
            $paymentMethod = PaymentMethod::retrieve($payment_method_id);
            $paymentMethod->detach();
            return response()->json([
                'message' => 'Método de pago eliminado correctamente.',
            ], Response::HTTP_OK);
        } catch (\Stripe\Exception\ApiErrorException $e) {
            return response()->json(['error' => 'Error con Stripe: ' . $e->getMessage()], 500);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Error inesperado: ' . $e->getMessage()], 500);
        }
    }

    public function setDefaultPaymentMethod(string $stripe_customer_id, string $payment_method_id): JsonResponse
    {
        try {
            $paymentMethod = PaymentMethod::retrieve($payment_method_id);
            if ($paymentMethod->customer !== $stripe_customer_id) {
                return response()->json(['error' => 'El método de pago no pertenece a este cliente.'], 500);
            }

            \Stripe\Customer::update($stripe_customer_id, [
                'invoice_settings' => [
                    'default_payment_method' => $payment_method_id,
                ]
            ]);
            return response()->json([
                'message' => 'Método de pago establecido como predeterminado correctamente.'
            ], Response::HTTP_OK);
        } catch (\Stripe\Exception\ApiErrorException $e) {
            return response()->json(['error' => 'Error con Stripe: ' . $e->getMessage()], 500);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Error inesperado: ' . $e->getMessage()], 500);
        }
    }

    // public function getSubscriptionsCustomer(string $stripe_customer_id): JsonResponse
    // {
    //     try {
    //         $subscriptions = \Stripe\Subscription::all([
    //             'customer' => $stripe_customer_id,
    //             'status' => 'all', // puedes usar 'active' si lo prefieres
    //             'limit' => 1, // suponiendo una sola suscripción
    //             'expand' => ['data.default_payment_method', 'data.items.data.price'],
    //         ]);

    //         $subscription = $subscriptions->data[0] ?? null;

    //         if (!$subscription) {
    //             return response()->json(['message' => 'No hay suscripciones.'], Response::HTTP_OK);
    //         }

    //         $item = $subscription->items->data[0] ?? null;

    //         return response()->json([
    //             'subscription' => [
    //                 'id' => $subscription->id,
    //                 'status' => $subscription->status,
    //                 'current_period_start' => $subscription->current_period_start,
    //                 'current_period_end' => $subscription->current_period_end,
    //                 'cancel_at_period_end' => $subscription->cancel_at_period_end,
    //                 'default_payment_method_id' => optional($subscription->default_payment_method)->id,
    //                 'price' => [
    //                     'id' => $item->price->id ?? null,
    //                     'amount' => isset($item->price->unit_amount) ? $item->price->unit_amount / 100 : null,
    //                     'currency' => strtoupper($item->price->currency ?? 'usd'),
    //                     'interval' => $item->price->recurring->interval ?? null,
    //                 ]
    //             ]
    //         ], Response::HTTP_OK);
    //     } catch (\Stripe\Exception\ApiErrorException $e) {
    //         return response()->json(['error' => 'Error con Stripe: ' . $e->getMessage()], 500);
    //     } catch (\Exception $e) {
    //         return response()->json(['error' => 'Error inesperado: ' . $e->getMessage()], 500);
    //     }
    // }
}