<?php

namespace App\Http\Controllers;

use App\Models\Address;
use App\Models\Coupon;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Payment;
use App\Models\Setting;
use App\Models\TrackingUpdate;
use App\Support\NotificationManager;
use App\Support\PaymentGatewayManager;
use App\Support\PricingCalculator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class OrderController extends Controller
{
    public function index(Request $request)
    {
        return view('orders.index', [
            'orders' => $request->user()->orders()->with(['items.document', 'address', 'payments', 'trackingUpdates'])->latest()->get(),
        ]);
    }

    public function create(Request $request)
    {
        return view('orders.create', [
            'documents' => $request->user()->documents()->latest()->get(),
            'addresses' => $request->user()->addresses()->latest()->get(),
            'paymentMethods' => PaymentGatewayManager::availableMethods(),
            'defaultProvider' => PaymentGatewayManager::activeProvider(),
        ]);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'document_id' => ['required', 'exists:documents,id'],
            'address_id' => ['nullable', 'exists:addresses,id'],
            'save_address' => ['nullable', 'boolean'],
            'address_label' => ['nullable', 'string', 'max:50'],
            'recipient_name' => ['required_without:address_id', 'nullable', 'string', 'max:255'],
            'phone' => ['required_without:address_id', 'nullable', 'string', 'max:20'],
            'line1' => ['required_without:address_id', 'nullable', 'string', 'max:255'],
            'line2' => ['nullable', 'string', 'max:255'],
            'landmark' => ['nullable', 'string', 'max:255'],
            'city' => ['required_without:address_id', 'nullable', 'string', 'max:100'],
            'state' => ['required_without:address_id', 'nullable', 'string', 'max:100'],
            'postal_code' => ['required_without:address_id', 'nullable', 'digits:6'],
            'country' => ['nullable', 'string', 'max:100'],
            'page_size' => ['required', 'in:A4,A5,ID Card,PVC,Paper Print,Premium Lamination'],
            'print_mode' => ['required', 'in:bw,color'],
            'sides' => ['required', 'in:single,double'],
            'copies' => ['required', 'integer', 'min:1', 'max:100'],
            'binding_type' => ['nullable', 'in:none,spiral,hard'],
            'lamination_type' => ['nullable', 'in:none,gloss,matte'],
            'pvc_printing' => ['nullable', 'boolean'],
            'payment_method' => ['required', 'in:upi,card,netbanking'],
            'coupon_code' => ['nullable', 'string', 'max:50'],
            'notes' => ['nullable', 'string', 'max:1000'],
        ]);

        $document = $request->user()->documents()->findOrFail($validated['document_id']);

        $address = $validated['address_id']
            ? $request->user()->addresses()->findOrFail($validated['address_id'])
            : null;

        if (!$address) {
            $address = Address::query()->create([
                'user_id' => $request->user()->id,
                'label' => $validated['address_label'] ?: 'Delivery Address',
                'recipient_name' => $validated['recipient_name'],
                'phone' => $validated['phone'],
                'line1' => $validated['line1'],
                'line2' => $validated['line2'] ?? null,
                'landmark' => $validated['landmark'] ?? null,
                'city' => $validated['city'],
                'state' => $validated['state'],
                'postal_code' => $validated['postal_code'],
                'country' => $validated['country'] ?: 'India',
                'is_default' => !$request->user()->addresses()->exists() || $request->boolean('save_address'),
                'is_verified' => false,
            ]);
        }

        $coupon = null;
        if (!empty($validated['coupon_code'])) {
            $coupon = Coupon::query()
                ->where('code', strtoupper($validated['coupon_code']))
                ->where('is_active', true)
                ->first();
        }

        $pricing = PricingCalculator::calculate([
            'page_count' => $document->page_count,
            'copies' => (int) $validated['copies'],
            'print_mode' => $validated['print_mode'],
            'sides' => $validated['sides'],
            'binding_type' => $validated['binding_type'] ?? 'none',
            'lamination_type' => $validated['lamination_type'] ?? 'none',
            'pvc_printing' => $request->boolean('pvc_printing'),
            'coupon' => $coupon,
        ]);

        $paymentProvider = PaymentGatewayManager::activeProvider();
        $invoiceNumber = 'INV-' . now()->format('Ymd') . '-' . strtoupper(Str::random(5));
        $defaultCourier = (string) Setting::getValue('courier_default_partner', 'Delhivery');

        $order = DB::transaction(function () use ($request, $validated, $document, $address, $pricing, $coupon, $paymentProvider, $invoiceNumber, $defaultCourier) {
            $order = Order::query()->create([
                'user_id' => $request->user()->id,
                'address_id' => $address->id,
                'coupon_id' => $coupon?->id,
                'order_number' => 'ORD-' . now()->format('Ymd') . '-' . strtoupper(Str::random(6)),
                'status' => 'pending',
                'currency' => 'INR',
                'subtotal' => $pricing['subtotal'],
                'discount_amount' => $pricing['discount'],
                'delivery_amount' => $pricing['delivery'],
                'gst_amount' => $pricing['gst'],
                'total_amount' => $pricing['total'],
                'payment_status' => 'pending',
                'payment_provider' => $paymentProvider,
                'payment_method' => $validated['payment_method'],
                'delivery_partner' => $defaultCourier,
                'invoice_number' => $invoiceNumber,
                'notes' => $validated['notes'] ?? null,
            ]);

            OrderItem::query()->create([
                'order_id' => $order->id,
                'document_id' => $document->id,
                'item_name' => $document->title,
                'page_size' => $validated['page_size'],
                'print_mode' => $validated['print_mode'],
                'sides' => $validated['sides'],
                'copies' => (int) $validated['copies'],
                'binding_type' => $validated['binding_type'] ?? 'none',
                'lamination_type' => $validated['lamination_type'] ?? 'none',
                'pvc_printing' => $request->boolean('pvc_printing'),
                'page_count' => $document->page_count,
                'unit_price' => $pricing['unit_rate'],
                'total_price' => $pricing['subtotal'],
                'options_json' => $pricing['breakdown'],
            ]);

            Payment::query()->create([
                'order_id' => $order->id,
                'user_id' => $request->user()->id,
                'amount' => $pricing['total'],
                'currency' => 'INR',
                'provider' => $paymentProvider,
                'status' => 'pending',
                'payload' => [
                    'mode' => Setting::getValue('payment_demo_mode', true) ? 'demo' : 'live-ready',
                    'method' => $validated['payment_method'],
                ],
            ]);

            TrackingUpdate::query()->create([
                'order_id' => $order->id,
                'status' => 'pending',
                'title' => 'Order created',
                'description' => 'Customer order received and waiting for payment confirmation.',
                'location' => $address->city . ', ' . $address->state,
                'created_by' => $request->user()->id,
            ]);

            return $order;
        });

        $order->load('user');
        NotificationManager::orderPlaced($order);

        return redirect()->route('payments.show', $order)->with('status', 'Order placed successfully. Complete the payment to move it into processing.');
    }

    public function show(Request $request, Order $order)
    {
        abort_unless($order->user_id === $request->user()->id || $request->user()->isAdmin(), 403);

        $order->load(['items.document', 'address', 'payments', 'coupon', 'trackingUpdates']);

        return view('orders.show', [
            'order' => $order,
        ]);
    }

    public function invoice(Request $request, Order $order)
    {
        abort_unless($order->user_id === $request->user()->id || $request->user()->isAdmin(), 403);

        $order->load(['items.document', 'address', 'coupon']);

        return view('orders.invoice', [
            'order' => $order,
            'platformName' => Setting::getValue('platform_name', 'Print Cards'),
            'supportEmail' => Setting::getValue('platform_support_email', 'support@printcards.test'),
        ]);
    }
}
