<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\Models\MembershipPlan;
use App\Models\Payment;
use App\Models\Subscription;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class CheckoutController extends Controller
{
    private function options(): \Iyzipay\Options
    {
        $opt = new \Iyzipay\Options();
        $opt->setApiKey(config('iyzico.api_key'));
        $opt->setSecretKey(config('iyzico.secret_key'));
        $opt->setBaseUrl(config('iyzico.base_url'));
        return $opt;
    }

    public function show(MembershipPlan $plan)
    {
        abort_if(!$plan->is_active || !$plan->is_public, 404);
        return view('frontend.checkout.show', compact('plan'));
    }

    public function initialize(Request $request, MembershipPlan $plan)
    {
        abort_if(!$plan->is_active || !$plan->is_public, 404);

        $v = $request->validate([
            'full_name'   => 'required|string|max:100',
            'phone'       => 'required|string|max:20',
            'city'        => 'required|string|max:80',
            'address'     => 'required|string|max:300',
            'identity_no' => 'nullable|digits:11',
        ]);

        $user = Auth::user();
        $conversationId = Str::uuid()->toString();
        $price = number_format($plan->price, 2, '.', '');

        $parts = explode(' ', trim($v['full_name']), 2);
        $firstName = $parts[0];
        $lastName  = $parts[1] ?? '-';

        $payment = Payment::create([
            'user_id'         => $user->id,
            'plan_id'         => $plan->id,
            'conversation_id' => $conversationId,
            'amount'          => $plan->price,
            'status'          => 'pending',
        ]);

        $req = new \Iyzipay\Request\CreateCheckoutFormInitializeRequest();
        $req->setLocale(\Iyzipay\Model\Locale::TR);
        $req->setConversationId($conversationId);
        $req->setPrice($price);
        $req->setPaidPrice($price);
        $req->setCurrency(\Iyzipay\Model\Currency::TL);
        $req->setBasketId('payment-' . $payment->id);
        $req->setPaymentGroup(\Iyzipay\Model\PaymentGroup::PRODUCT);
        $req->setCallbackUrl(route('checkout.callback'));
        $req->setEnabledInstallments([1, 2, 3, 6, 9, 12]);

        $buyer = new \Iyzipay\Model\Buyer();
        $buyer->setId('u' . $user->id);
        $buyer->setName($firstName);
        $buyer->setSurname($lastName);
        $buyer->setGsmNumber('+9' . preg_replace('/\D/', '', $v['phone']));
        $buyer->setEmail($user->email);
        $buyer->setIdentityNumber($v['identity_no'] ?: '11111111111');
        $buyer->setRegistrationAddress($v['address']);
        $buyer->setIp($request->ip());
        $buyer->setCity($v['city']);
        $buyer->setCountry('Turkey');
        $req->setBuyer($buyer);

        $addr = new \Iyzipay\Model\Address();
        $addr->setContactName($v['full_name']);
        $addr->setCity($v['city']);
        $addr->setCountry('Turkey');
        $addr->setAddress($v['address']);
        $req->setBillingAddress($addr);
        $req->setShippingAddress($addr);

        $item = new \Iyzipay\Model\BasketItem();
        $item->setId('plan' . $plan->id);
        $item->setName($plan->name . ' Premium (' . $plan->duration_days . ' gün)');
        $item->setCategory1('Dijital Ürün');
        $item->setItemType(\Iyzipay\Model\BasketItemType::VIRTUAL);
        $item->setPrice($price);
        $req->setBasketItems([$item]);

        $form = \Iyzipay\Model\CheckoutFormInitialize::create($req, $this->options());

        if ($form->getStatus() !== 'success') {
            $payment->update(['status' => 'failed', 'error_message' => $form->getErrorMessage()]);
            return back()->withErrors(['general' => 'Ödeme başlatılamadı: ' . $form->getErrorMessage()]);
        }

        $payment->update(['token' => $form->getToken()]);

        return view('frontend.checkout.form', [
            'plan'        => $plan,
            'formContent' => $form->getCheckoutFormContent(),
        ]);
    }

    public function callback(Request $request)
    {
        $token = $request->input('token');

        if (!$token) {
            return redirect()->route('checkout.failed');
        }

        $payment = Payment::where('token', $token)->where('status', 'pending')->first();

        if (!$payment) {
            return redirect()->route('checkout.failed');
        }

        $req = new \Iyzipay\Request\RetrieveCheckoutFormRequest();
        $req->setLocale(\Iyzipay\Model\Locale::TR);
        $req->setConversationId($payment->conversation_id);
        $req->setToken($token);

        $result = \Iyzipay\Model\CheckoutForm::retrieve($req, $this->options());

        if ($result->getStatus() === 'success' && $result->getPaymentStatus() === 'SUCCESS') {
            $payment->update([
                'status'            => 'success',
                'iyzico_payment_id' => $result->getPaymentId(),
                'paid_at'           => now(),
            ]);

            $plan = $payment->plan;
            $user = $payment->user;
            $hasEver = Subscription::where('user_id', $user->id)->exists();
            $bonus = ($hasEver === false && ($plan->trial_days ?? 0) > 0) ? $plan->trial_days : 0;
            $expiresAt = now()->addDays($plan->duration_days + $bonus);

            Subscription::create([
                'user_id'        => $user->id,
                'plan_id'        => $plan->id,
                'status'         => 'active',
                'starts_at'      => now(),
                'expires_at'     => $expiresAt,
                'payment_method' => 'iyzico',
                'payment_ref'    => $result->getPaymentId(),
            ]);

            $user->update([
                'membership'         => 'premium',
                'premium_expires_at' => $expiresAt,
            ]);

            session(['checkout_plan_name' => $plan->name]);
            return redirect()->route('checkout.success');
        }

        $payment->update([
            'status'        => 'failed',
            'error_message' => $result->getErrorMessage(),
        ]);

        return redirect()->route('checkout.failed');
    }

    public function success()
    {
        return view('frontend.checkout.success');
    }

    public function failed()
    {
        return view('frontend.checkout.failed');
    }
}
