<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\ShippingMethod;
use App\Models\ResellerPackage;
use App\Models\ResellerWalletTransaction;
use App\Models\ResellerWithdrawRequest;
use App\Models\BdDivision;
use App\Models\BdDistrict;
use App\Models\BdUpazila;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Exception;

class ResellerApiController extends Controller
{
    /**
     * Get reseller dashboard stats.
     */
    public function resellerStats(Request $request)
    {
        $user = Auth::user();

        if ($user->role !== 'reseller') {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized. Only resellers can access stats.',
            ], 403);
        }

        $balance = $user->getWalletBalance();
        $totalOrders = $user->resellerOrders()->count();
        $totalSales = (float) $user->resellerOrders()->sum('subtotal');
        $totalProfit = (float) $user->resellerOrders()->sum('total_reseller_profit');
        $totalWithdrawn = (float) $user->withdrawRequests()->where('status', 'approved')->sum('amount');

        return response()->json([
            'success' => true,
            'data' => [
                'wallet_balance' => $balance,
                'total_orders' => $totalOrders,
                'total_sales' => $totalSales,
                'total_profit' => $totalProfit,
                'total_withdrawn' => $totalWithdrawn,
                'package_name' => $user->resellerPackage?->name ?? 'No Active Package',
                'reseller_status' => $user->reseller_status,
                'expires_at' => $user->reseller_expires_at ? $user->reseller_expires_at->format('Y-m-d H:i:s') : null,
            ]
        ]);
    }

    /**
     * Update reseller payment setting credentials.
     */
    public function updatePaymentSettings(Request $request)
    {
        $user = Auth::user();

        $validator = Validator::make($request->all(), [
            'reseller_bkash_number' => 'nullable|string|max:15',
            'reseller_nagad_number' => 'nullable|string|max:15',
            'reseller_rocket_number' => 'nullable|string|max:15',
            'reseller_bank_details' => 'nullable|string|max:1000',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        $user->update($request->only([
            'reseller_bkash_number',
            'reseller_nagad_number',
            'reseller_rocket_number',
            'reseller_bank_details',
        ]));

        return response()->json([
            'success' => true,
            'message' => 'Payment settings updated successfully.',
            'data' => $user->only([
                'reseller_bkash_number',
                'reseller_nagad_number',
                'reseller_rocket_number',
                'reseller_bank_details',
            ])
        ]);
    }

    /**
     * Get products with calculated reseller pricing.
     */
    public function resellerProducts(Request $request)
    {
        $query = Product::query()
            ->where('is_visible', true)
            ->with(['variants', 'media', 'category']);

        // Search filter
        if ($request->filled('search')) {
            $query->search($request->input('search'));
        }

        // Specific Product ID filter
        if ($request->filled('product_id')) {
            $query->where('id', $request->input('product_id'));
        }

        // Category filter
        if ($request->filled('category_id')) {
            $query->where('category_id', $request->input('category_id'));
        }

        $products = $query->paginate(16);

        // Map products to include calculated reseller price and retail price
        $products->getCollection()->transform(function ($product) {
            $data = $product->toArray();
            $data['reseller_price'] = $product->reseller_price; // derived from cost_price * 1.15
            $data['retail_price'] = $product->effective_price; // sale_price if present, else price
            return $data;
        });

        return response()->json([
            'success' => true,
            'data' => $products
        ]);
    }

    /**
     * Submit a new reseller order.
     */
    public function placeResellerOrder(Request $request)
    {
        $user = Auth::user();

        $validator = Validator::make($request->all(), [
            'customer_name' => 'required|string|max:255',
            'customer_phone' => 'required|string|min:11|max:15',
            'customer_email' => 'nullable|email',
            'selected_division_id' => 'required|exists:bd_divisions,id',
            'selected_district_id' => 'required|exists:bd_districts,id',
            'selected_upazila_id' => 'required|exists:bd_upazilas,id',
            'street_address' => 'required|string|max:500',
            'selected_shipping_method_id' => 'nullable|exists:shipping_methods,id',
            'payment_method' => 'required|string',
            'notes' => 'nullable|string|max:1000',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.sku' => 'required|string',
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.price' => 'required|numeric|min:0', // Custom selling price
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        DB::beginTransaction();

        try {
            $subtotal = 0.00;
            $totalResellerPrice = 0.00;
            $totalResellerProfit = 0.00;
            $orderItems = [];

            // 1. Stock check & pricing calculations
            foreach ($request->items as $itemData) {
                $product = Product::findOrFail($itemData['product_id']);
                
                // Fetch reseller wholesale price
                $wholesalePrice = $product->reseller_price;

                if ($product->quantity < $itemData['quantity']) {
                    throw new Exception("Stock error: {$product->name} does not have enough stock.");
                }

                $orderItems[] = [
                    'product_id' => $product->id,
                    'sku' => $itemData['sku'],
                    'quantity' => $itemData['quantity'],
                    'price' => (float) $itemData['price'], // Reseller's custom selling price
                    'reseller_price' => (float) $wholesalePrice,
                    'reseller_profit' => (float) ($itemData['price'] - $wholesalePrice),
                ];

                $subtotal += $itemData['price'] * $itemData['quantity'];
                $totalResellerPrice += $wholesalePrice * $itemData['quantity'];
            }

            $totalResellerProfit = $subtotal - $totalResellerPrice;

            // 2. Fetch shipping cost
            $shippingMethodId = null;
            $shippingCost = 0.00;
            if ($request->filled('selected_shipping_method_id')) {
                $shippingMethod = ShippingMethod::findOrFail($request->selected_shipping_method_id);
                $shippingMethodId = $shippingMethod->id;
                $shippingCost = (float) $shippingMethod->cost;
            }

            // 3. Generate order number
            $resellerCode = $user->reseller_code ?? \App\Models\User::generateUniqueResellerCode();
            if (!$user->reseller_code) {
                $user->reseller_code = $resellerCode;
                $user->saveQuietly();
            }
            $orderNumber = 'RES-' . $resellerCode . '-' . date('ymd') . '-' . rand(1000, 9999);
            while (Order::where('order_number', $orderNumber)->exists()) {
                $orderNumber = 'RES-' . $resellerCode . '-' . date('ymd') . '-' . rand(1000, 9999);
            }

            // 4. Format shipping address
            $div = BdDivision::find($request->selected_division_id)?->name;
            $dist = BdDistrict::find($request->selected_district_id)?->name;
            $up = BdUpazila::find($request->selected_upazila_id)?->name;
            $shippingAddress = "{$request->street_address}, {$up}, {$dist}, {$div}";

            // 5. Create Order
            $order = Order::create([
                'order_number'          => $orderNumber,
                'user_id'               => $user->id,
                'is_reseller_order'     => true,
                'reseller_id'           => $user->id,
                'customer_name'         => $request->customer_name,
                'customer_phone'        => $request->customer_phone,
                'customer_email'        => $request->customer_email,
                'shipping_address'      => $shippingAddress,
                'billing_address'       => $shippingAddress,
                'shipping_method_id'    => $shippingMethodId,
                'shipping_cost'         => $shippingCost,
                'payment_method'        => $request->payment_method,
                'payment_status'        => 'pending',
                'status'                => 'pending',
                'subtotal'              => $subtotal,
                'grand_total'           => $subtotal + $shippingCost,
                'total_reseller_price'  => $totalResellerPrice,
                'total_reseller_profit' => $totalResellerProfit,
                'notes'                 => $request->notes,
            ]);

            // 6. Save items & decrement stock
            foreach ($orderItems as $item) {
                $product = Product::find($item['product_id']);
                OrderItem::create([
                    'order_id'        => $order->id,
                    'product_id'      => $item['product_id'],
                    'product_name'    => $product?->name ?? $item['name'] ?? 'Product',
                    'product_sku'     => $item['sku'] ?? ($product?->sku ?? 'SKU'),
                    'quantity'        => $item['quantity'],
                    'price'           => $item['price'],
                    'reseller_price'  => $item['reseller_price'],
                    'reseller_profit' => $item['reseller_profit'],
                ]);

                // Decrement stock
                $product?->decrement('quantity', $item['quantity']);
            }

            // Explicitly update order totals after all items are saved
            // (the saved hook may have run before items existed)
            $order->updateQuietly([
                'subtotal'              => $subtotal,
                'grand_total'           => $subtotal + $shippingCost,
                'total_reseller_price'  => $totalResellerPrice,
                'total_reseller_profit' => $totalResellerProfit,
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Reseller order placed successfully!',
                'data' => [
                    'order_id' => $order->id,
                    'order_number' => $order->order_number,
                ]
            ]);

        } catch (Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get reseller order list.
     */
    public function resellerOrders(Request $request)
    {
        $user = Auth::user();

        $orders = $user->resellerOrders()
            ->with(['items.product'])
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json([
            'success' => true,
            'data' => $orders
        ]);
    }

    /**
     * Get wallet transactions ledger.
     */
    public function walletTransactions(Request $request)
    {
        $user = Auth::user();

        $transactions = $user->walletTransactions()
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json([
            'success' => true,
            'data' => $transactions
        ]);
    }

    /**
     * Get payout withdraw requests and make a new request.
     */
    public function withdrawRequests(Request $request)
    {
        $user = Auth::user();

        $requests = $user->withdrawRequests()
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json([
            'success' => true,
            'data' => $requests
        ]);
    }

    /**
     * Submit a new withdrawal/payout request.
     */
    public function storeWithdrawRequest(Request $request)
    {
        $user = Auth::user();

        $validator = Validator::make($request->all(), [
            'amount' => 'required|numeric|min:100',
            'payment_method' => 'required|in:bkash,nagad,rocket,bank',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        $balance = $user->getWalletBalance();
        if ($request->amount > $balance) {
            return response()->json([
                'success' => false,
                'message' => 'Insufficient wallet balance. Current balance is ৳' . number_format($balance, 2)
            ], 422);
        }

        // Fetch saved account details from profile based on method
        $accountDetails = match ($request->payment_method) {
            'bkash' => $user->reseller_bkash_number,
            'nagad' => $user->reseller_nagad_number,
            'rocket' => $user->reseller_rocket_number,
            'bank' => $user->reseller_bank_details,
        };

        if (empty($accountDetails)) {
            return response()->json([
                'success' => false,
                'message' => 'Please set up your account details in Payment Settings first.'
            ], 422);
        }

        $withdraw = ResellerWithdrawRequest::create([
            'user_id' => $user->id,
            'amount' => $request->amount,
            'payment_method' => $request->payment_method,
            'account_number' => $accountDetails,
            'status' => 'pending',
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Payout request submitted successfully!',
            'data' => $withdraw
        ]);
    }

    /**
     * Purchase/Renew a subscription package.
     */
    public function purchasePackage(Request $request)
    {
        $user = Auth::user();

        $validator = Validator::make($request->all(), [
            'package_id' => 'required|exists:reseller_packages,id',
            'payment_method' => 'required|string',
            'sender_number' => 'nullable|string',
            'transaction_id' => 'required|string|unique:reseller_wallet_transactions,description', // crude txn id unique check
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        $package = ResellerPackage::findOrFail($request->package_id);

        $description = "সদস্যপদ প্ল্যান ক্রয়: {$package->name} (মেথড: " . strtoupper($request->payment_method) . ", TxnID: {$request->transaction_id})";
        if ($request->filled('sender_number')) {
            $description = "সদস্যপদ প্ল্যান ক্রয়: {$package->name} (মেথড: " . strtoupper($request->payment_method) . ", Sender: {$request->sender_number}, TxnID: {$request->transaction_id})";
        }

        // Create pending package verification transaction
        $transaction = ResellerWalletTransaction::create([
            'user_id' => $user->id,
            'amount' => $package->price,
            'type' => 'debit',
            'status' => 'pending',
            'description' => $description,
        ]);

        // Link package purchase
        $user->update([
            'reseller_package_id' => $package->id,
            'reseller_status' => 'pending',
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Package purchase request submitted! Admin will verify and activate your membership.',
            'data' => $transaction
        ]);
    }

    /**
     * Get shipping cost for a district (no cart required — for reseller order preview).
     */
    public function shippingCostByDistrict(Request $request)
    {
        $request->validate([
            'district_id' => 'required|integer|exists:bd_districts,id',
        ]);

        $district = BdDistrict::find($request->district_id);
        $zone = ($district && strtolower($district->name) === 'dhaka') ? 'inside_dhaka' : 'outside_dhaka';

        $methods = ShippingMethod::where('zone', $zone)
            ->where('is_active', true)
            ->where('pricing_type', 'flat')
            ->get();

        $formattedMethods = $methods->map(function ($method) {
            return [
                'id'             => $method->id,
                'name'           => $method->name,
                'zone'           => $method->zone,
                'cost'           => (float) $method->cost,
                'pricing_type'   => $method->pricing_type,
                'estimated_days' => $method->estimated_days,
            ];
        });

        return response()->json([
            'success' => true,
            'data'    => $formattedMethods,
        ]);
    }

    /**
     * Get single reseller order detail.
     */
    public function resellerOrderDetail(Request $request, $orderNumber)
    {
        $user = Auth::user();

        $order = Order::where('reseller_id', $user->id)
            ->where('order_number', $orderNumber)
            ->where('is_reseller_order', true)
            ->with([
                'items.product.media',
                'shippingMethod',
            ])
            ->firstOrFail();

        return response()->json([
            'success' => true,
            'data' => [
                'order_number'          => $order->order_number,
                'status'                => $order->status,
                'payment_method'        => $order->payment_method,
                'payment_status'        => $order->payment_status,
                'created_at'            => $order->created_at,
                'customer_name'         => $order->customer_name,
                'customer_phone'        => $order->customer_phone,
                'customer_email'        => $order->customer_email,
                'shipping_address'      => $order->shipping_address,
                'shipping_method'       => $order->shippingMethod?->name,
                'shipping_cost'         => (float) $order->shipping_cost,
                'subtotal'              => (float) $order->subtotal,
                'grand_total'           => (float) $order->grand_total,
                'total_reseller_price'  => (float) $order->total_reseller_price,
                'total_reseller_profit' => (float) $order->total_reseller_profit,
                'notes'                 => $order->notes,
                'items'                 => $order->items->map(function ($item) {
                    return [
                        'product_name'    => $item->product_name,
                        'product_sku'     => $item->product_sku,
                        'quantity'        => $item->quantity,
                        'price'           => (float) $item->price,
                        'reseller_price'  => (float) $item->reseller_price,
                        'reseller_profit' => (float) $item->reseller_profit,
                        'total'           => (float) ($item->price * $item->quantity),
                        'image'           => $item->product?->media->first()?->original_url ?? null,
                    ];
                }),
            ]
        ]);
    }

    /**
     * Update reseller profile info and upload verification documents.
     */
    public function updateProfile(Request $request)
    {
        $user = Auth::user();

        $rules = [
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email,' . $user->id,
            'phone' => 'nullable|string|max:20|unique:users,phone,' . $user->id,
            'password' => 'nullable|string|min:8|confirmed',
            'avatar' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'reseller_nid_front' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'reseller_nid_back' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'reseller_passport_photo' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'reseller_store_name' => 'nullable|string|max:255',
            'reseller_fb_profile' => 'nullable|string|max:255',
            'reseller_fb_page' => 'nullable|string|max:255',
            'reseller_website' => 'nullable|string|max:255',
            'reseller_whatsapp' => 'nullable|string|max:255',
            'reseller_telegram' => 'nullable|string|max:255',
        ];

        $validator = Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        $data = [
            'name' => $request->name,
            'email' => $request->email,
            'phone' => $request->phone,
            'reseller_store_name' => $request->reseller_store_name,
            'reseller_fb_profile' => $request->reseller_fb_profile,
            'reseller_fb_page' => $request->reseller_fb_page,
            'reseller_website' => $request->reseller_website,
            'reseller_whatsapp' => $request->reseller_whatsapp,
            'reseller_telegram' => $request->reseller_telegram,
        ];

        if ($request->filled('password')) {
            $data['password'] = \Illuminate\Support\Facades\Hash::make($request->password);
        }

        // Handle File Uploads
        $fileFields = ['avatar', 'reseller_nid_front', 'reseller_nid_back', 'reseller_passport_photo'];
        foreach ($fileFields as $field) {
            if ($request->hasFile($field)) {
                // Delete old file if exists
                if ($user->{$field}) {
                    \Illuminate\Support\Facades\Storage::disk('public')->delete($user->{$field});
                }
                // Store new file
                $path = $request->file($field)->store('resellers', 'public');
                $data[$field] = $path;
            }
        }

        $uploadedVerificationDoc = $request->hasFile('reseller_nid_front') || 
                                   $request->hasFile('reseller_nid_back') || 
                                   $request->hasFile('reseller_passport_photo');

        if ($uploadedVerificationDoc && in_array($user->reseller_status, ['pending', 'rejected'])) {
            $data['reseller_status'] = 'under_review';
        }

        $user->update($data);

        // Send notification to admins if status changed to under_review
        if ($user->reseller_status === 'under_review' && $uploadedVerificationDoc) {
            try {
                $admins = \App\Models\User::where('role', 'admin')->get();
                foreach ($admins as $admin) {
                    \Filament\Notifications\Notification::make()
                        ->title('New Reseller Verification Request')
                        ->body($user->name . ' has uploaded verification documents and is waiting for review.')
                        ->icon('heroicon-o-document-magnifying-glass')
                        ->iconColor('warning')
                        ->actions([
                            \Filament\Actions\Action::make('view')
                                ->label('Review')
                                ->button()
                                ->url(route('filament.admin.resources.resellers.edit', ['record' => $user->id])),
                        ])
                        ->sendToDatabase($admin);
                }
            } catch (\Throwable $e) {
                \Illuminate\Support\Facades\Log::error('Reseller notification error: ' . $e->getMessage());
            }
        }

        // Map absolute URLs for UI response
        $apiUrl = url('/');
        $avatarUrl = $user->avatar ? (strpos($user->avatar, 'http') === 0 ? $user->avatar : $apiUrl . '/storage/' . $user->avatar) : null;
        $nidFrontUrl = $user->reseller_nid_front ? $apiUrl . '/storage/' . $user->reseller_nid_front : null;
        $nidBackUrl = $user->reseller_nid_back ? $apiUrl . '/storage/' . $user->reseller_nid_back : null;
        $passportPhotoUrl = $user->reseller_passport_photo ? $apiUrl . '/storage/' . $user->reseller_passport_photo : null;

        return response()->json([
            'success' => true,
            'message' => 'Profile updated successfully!',
            'user' => array_merge($user->toArray(), [
                'avatar_url' => $avatarUrl,
                'reseller_nid_front_url' => $nidFrontUrl,
                'reseller_nid_back_url' => $nidBackUrl,
                'reseller_passport_photo_url' => $passportPhotoUrl,
            ])
        ]);
    }

    /**
     * Get active reseller community groups.
     */
    public function communityGroups()
    {
        $groups = \App\Models\ResellerCommunityGroup::where('is_active', true)
            ->orderBy('sort_order', 'asc')
            ->get();

        return response()->json([
            'success' => true,
            'groups' => $groups
        ]);
    }
}
