<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\Models\SellerAccount;
use App\Models\SellerProduct;
use App\Models\SellerUpgrade;
use App\Models\SellerWithdrawal;
use App\Models\Setting;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class MarketplaceController extends Controller
{
    // ── Public marketplace ──────────────────────────────────────────────────

    public function index(Request $request)
    {
        $q        = $request->q;
        $currency = optional(Setting::first())->website_currency ?? '';

        // Admin products
        $adminProducts = \App\Models\Product::where('status', true)
            ->with('productCategory')
            ->withCount(['unsoldProductDetails as available_count'])
            ->when($q, fn($query) => $query->where('name', 'like', "%$q%")
                ->orWhereHas('productCategory', fn($c) => $c->where('name', 'like', "%$q%")))
            ->having('available_count', '>', 0)
            ->get()
            ->map(fn($p) => [
                'id'          => $p->id,
                'type'        => 'admin',
                'title'       => $p->name,
                'category'    => optional($p->productCategory)->name ?? 'Account',
                'description' => $p->description,
                'price'       => $p->price,
                'stock'       => $p->available_count,
                'image'       => $p->image,
                'seller'      => 'Admin',
            ]);

        // Seller products
        $sellerProducts = SellerProduct::where('status', true)
            ->with('user')
            ->withCount('availableAccounts as available_count')
            ->when($q, fn($query) => $query->where('title', 'like', "%$q%")
                ->orWhere('category', 'like', "%$q%"))
            ->having('available_count', '>', 0)
            ->get()
            ->map(fn($p) => [
                'id'          => $p->id,
                'type'        => 'seller',
                'title'       => $p->title,
                'category'    => $p->category ?? 'Account',
                'description' => $p->description,
                'price'       => $p->price,
                'stock'       => $p->available_count,
                'image'       => null,
                'seller'      => $p->user->fname ?? 'Seller',
            ]);

        $products = $adminProducts->merge($sellerProducts)->sortByDesc('id')->values();

        return view('frontend.marketplace.index', [
            'title'    => 'Marketplace',
            'products' => $products,
            'currency' => $currency,
        ]);
    }

    public function show($type, $id)
    {
        $currency = optional(Setting::first())->website_currency ?? '';

        if ($type === 'admin') {
            // Redirect to the existing buy accounts product detail page
            return redirect()->route('user.accounts.product', $id);
        }

        $product = SellerProduct::with('user')
            ->withCount('availableAccounts as available_count')
            ->where('status', true)
            ->findOrFail($id);

        return view('frontend.marketplace.show', [
            'title'    => $product->title,
            'item'     => [
                'id'          => $product->id,
                'type'        => 'seller',
                'title'       => $product->title,
                'category'    => $product->category ?? 'Account',
                'description' => $product->description,
                'price'       => $product->price,
                'stock'       => $product->available_count,
                'image'       => null,
                'seller'      => $product->user->fname . ' ' . $product->user->lname,
            ],
            'currency' => $currency,
        ]);
    }

    public function purchase(Request $request, $type, $id)
    {
        // Admin products: delegate to the main AccountProductController purchase via internal call
        if ($type === 'admin') {
            abort(404); // admin products go through user.accounts.product page directly
        }

        $user     = Auth::user()->fresh();
        $settings = Setting::first();
        $product  = SellerProduct::where('status', true)->findOrFail($id);
        $account  = SellerAccount::where('seller_product_id', $product->id)
            ->where('is_sold', false)->lockForUpdate()->first();

        if (!$account) return back()->with('error', 'No accounts available for this product.');
        if ($user->balance < $product->price) return back()->with('error', 'Insufficient wallet balance.');

        $feePercent = (float) ($settings->seller_fee ?? 0);
        $fee        = round($product->price * $feePercent / 100, 2);
        $sellerEarn = $product->price - $fee;

        DB::transaction(function () use ($user, $product, $account, $sellerEarn, $fee) {
            $buyerBalanceBefore = $user->balance;
            $user->decrement('balance', $product->price);
            $account->update(['is_sold' => true, 'buyer_id' => $user->id]);

            Transaction::create([
                'user_id'        => $user->id,
                'type'           => 'debit',
                'amount'         => $product->price,
                'balance_before' => $buyerBalanceBefore,
                'balance_after'  => $buyerBalanceBefore - $product->price,
                'source'         => 'marketplace_purchase',
                'reference'      => 'account_' . $account->id,
                'description'    => 'Marketplace purchase: ' . $product->title,
            ]);

            $seller              = $product->user;
            $sellerBalanceBefore = $seller->seller_balance;
            $seller->increment('seller_balance', $sellerEarn);

            Transaction::create([
                'user_id'        => $seller->id,
                'type'           => 'credit',
                'amount'         => $sellerEarn,
                'balance_before' => $sellerBalanceBefore,
                'balance_after'  => $sellerBalanceBefore + $sellerEarn,
                'source'         => 'marketplace_sale',
                'reference'      => 'account_' . $account->id,
                'description'    => 'Sale: ' . $product->title . ' (fee: ' . $fee . ')',
            ]);
        });

        if ($request->wantsJson()) {
            return response()->json(['status' => 'success', 'message' => 'Purchase successful! Check your purchases.']);
        }

        return redirect()->route('user.marketplace.my-purchases')
            ->with('success', 'Purchase successful! Check your purchases.');
    }

    // ── Upgrade to seller ───────────────────────────────────────────────────

    public function upgradePage()
    {
        $settings = Setting::first();
        $pending  = SellerUpgrade::where('user_id', Auth::id())
            ->where('status', 'pending')->exists();

        return view('frontend.marketplace.upgrade', [
            'title'    => 'Become a Seller',
            'settings' => $settings,
            'pending'  => $pending,
        ]);
    }

    public function upgradeSubmit(Request $request)
    {
        $request->validate([
            'payment_method'  => 'required|in:wallet,manual',
            'payment_proof'   => 'required_if:payment_method,manual|nullable|image|mimes:jpeg,png,jpg|max:2048',
            'contact_name'    => 'required|string|max:255',
            'contact_email'   => 'required|email|max:255',
            'contact_phone'   => 'nullable|string|max:30',
        ]);

        $user     = Auth::user()->fresh();
        $settings = Setting::first();
        $fee      = (float) ($settings->seller_upgrade_fee ?? 0);

        if ($user->is_seller) {
            return back()->with('error', 'You are already a seller.');
        }

        $existing = SellerUpgrade::where('user_id', $user->id)
            ->where('status', 'pending')->exists();
        if ($existing) {
            return back()->with('error', 'You already have a pending upgrade request.');
        }

        $contactInfo = 'Name: ' . $request->contact_name
            . ' | Email: ' . $request->contact_email
            . ($request->contact_phone ? ' | Phone: ' . $request->contact_phone : '');

        if ($request->payment_method === 'wallet') {
            if ($user->balance < $fee) {
                return back()->with('error', 'Insufficient wallet balance. Please fund your wallet or use manual deposit.');
            }

            DB::transaction(function () use ($user, $fee, $contactInfo) {
                $balanceBefore = $user->balance;
                $user->decrement('balance', $fee);
                SellerUpgrade::create([
                    'user_id' => $user->id,
                    'amount'  => $fee,
                    'status'  => 'pending',
                    'note'    => 'Wallet payment | ' . $contactInfo,
                ]);
                Transaction::create([
                    'user_id'        => $user->id,
                    'type'           => 'debit',
                    'amount'         => $fee,
                    'balance_before' => $balanceBefore,
                    'balance_after'  => $balanceBefore - $fee,
                    'source'         => 'seller_upgrade',
                    'description'    => 'Seller upgrade fee payment',
                ]);
            });
        } else {
            $uploadPath = base_path('../assets/backend/images/seller_proofs');
            if (!is_dir($uploadPath)) {
                mkdir($uploadPath, 0755, true);
            }
            $file     = $request->file('payment_proof');
            $filename = time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
            $file->move($uploadPath, $filename);
            $path = 'assets/backend/images/seller_proofs/' . $filename;

            SellerUpgrade::create([
                'user_id'       => $user->id,
                'amount'        => $fee,
                'payment_proof' => $path,
                'status'        => 'pending',
                'note'          => 'Manual deposit | ' . $contactInfo,
            ]);
        }

        return back()->with('success', 'Upgrade request submitted. Admin will review shortly.');
    }

    // ── Seller dashboard ────────────────────────────────────────────────────

    public function sellerDashboard()
    {
        $this->requireSeller();
        $user = Auth::user()->fresh();

        $totalProducts  = SellerProduct::where('user_id', $user->id)->count();
        $totalSold      = SellerAccount::whereHas('product', fn($q) => $q->where('user_id', $user->id))
            ->where('is_sold', true)->count();
        $totalEarned    = SellerWithdrawal::where('user_id', $user->id)
            ->where('status', 'approved')->sum('net_amount');
        $pendingWithdraw = SellerWithdrawal::where('user_id', $user->id)
            ->where('status', 'pending')->sum('amount');

        return view('frontend.marketplace.seller.dashboard', [
            'title'           => 'Seller Dashboard',
            'user'            => $user,
            'totalProducts'   => $totalProducts,
            'totalSold'       => $totalSold,
            'totalEarned'     => $totalEarned,
            'pendingWithdraw' => $pendingWithdraw,
        ]);
    }

    // ── Seller products ─────────────────────────────────────────────────────

    public function sellerProducts()
    {
        $this->requireSeller();
        $products = SellerProduct::where('user_id', Auth::id())
            ->withCount(['accounts', 'availableAccounts'])
            ->latest()->paginate(15);

        return view('frontend.marketplace.seller.products', [
            'title'    => 'My Products',
            'products' => $products,
        ]);
    }

    public function sellerProductCreate()
    {
        $this->requireSeller();
        $categories = \App\Models\ProductCategory::where('status', true)->orderBy('sort')->get();
        return view('frontend.marketplace.seller.product-form', ['title' => 'Add Product', 'product' => null, 'categories' => $categories]);
    }

    public function sellerProductStore(Request $request)
    {
        $this->requireSeller();
        $request->validate([
            'title'       => 'required|string|max:255',
            'description' => 'nullable|string',
            'price'       => 'required|numeric|min:0.01',
            'category'    => 'nullable|string|max:100',
        ]);

        SellerProduct::create([
            'user_id'     => Auth::id(),
            'title'       => $request->title,
            'description' => $request->description,
            'price'       => $request->price,
            'category'    => $request->category,
            'status'      => true,
        ]);

        return redirect()->route('user.marketplace.seller.products')
            ->with('success', 'Product created.');
    }

    public function sellerProductEdit($id)
    {
        $this->requireSeller();
        $product    = SellerProduct::where('user_id', Auth::id())->findOrFail($id);
        $categories = \App\Models\ProductCategory::where('status', true)->orderBy('sort')->get();
        return view('frontend.marketplace.seller.product-form', ['title' => 'Edit Product', 'product' => $product, 'categories' => $categories]);
    }

    public function sellerProductUpdate(Request $request, $id)
    {
        $this->requireSeller();
        $request->validate([
            'title'       => 'required|string|max:255',
            'description' => 'nullable|string',
            'price'       => 'required|numeric|min:0.01',
            'category'    => 'nullable|string|max:100',
            'status'      => 'boolean',
        ]);

        $product = SellerProduct::where('user_id', Auth::id())->findOrFail($id);
        $product->update($request->only('title', 'description', 'price', 'category', 'status'));

        return redirect()->route('user.marketplace.seller.products')->with('success', 'Product updated.');
    }

    public function sellerProductDestroy($id)
    {
        $this->requireSeller();
        SellerProduct::where('user_id', Auth::id())->findOrFail($id)->delete();
        return back()->with('success', 'Product deleted.');
    }

    // ── Seller accounts (stock) ─────────────────────────────────────────────

    public function sellerAccounts($productId)
    {
        $this->requireSeller();
        $product  = SellerProduct::where('user_id', Auth::id())->findOrFail($productId);
        $accounts = SellerAccount::where('seller_product_id', $productId)->latest()->paginate(20);

        return view('frontend.marketplace.seller.accounts', [
            'title'    => 'Accounts – ' . $product->title,
            'product'  => $product,
            'accounts' => $accounts,
        ]);
    }

    public function sellerAccountsStore(Request $request, $productId)
    {
        $this->requireSeller();
        $request->validate(['accounts' => 'required|string']);
        $product = SellerProduct::where('user_id', Auth::id())->findOrFail($productId);

        $lines = array_filter(array_map('trim', explode("\n", $request->accounts)));
        foreach ($lines as $line) {
            SellerAccount::create(['seller_product_id' => $product->id, 'details' => $line]);
        }

        return back()->with('success', count($lines) . ' account(s) added.');
    }

    public function sellerAccountDestroy($id)
    {
        $this->requireSeller();
        $account = SellerAccount::whereHas('product', fn($q) => $q->where('user_id', Auth::id()))
            ->findOrFail($id);
        $account->delete();
        return back()->with('success', 'Account deleted.');
    }

    // ── Seller withdrawals ──────────────────────────────────────────────────

    public function sellerWithdrawals()
    {
        $this->requireSeller();
        $withdrawals = SellerWithdrawal::where('user_id', Auth::id())->latest()->paginate(15);
        $settings    = Setting::first();

        return view('frontend.marketplace.seller.withdrawals', [
            'title'       => 'Withdrawals',
            'withdrawals' => $withdrawals,
            'settings'    => $settings,
            'user'        => Auth::user()->fresh(),
        ]);
    }

    public function sellerWithdrawalStore(Request $request)
    {
        $this->requireSeller();
        $request->validate([
            'amount'          => 'required|numeric|min:1',
            'account_details' => 'required|string|max:500',
        ]);

        $user     = Auth::user()->fresh();
        $settings = Setting::first();
        $fee      = round($request->amount * ((float)($settings->seller_withdrawal_fee ?? 0)) / 100, 2);
        $net      = $request->amount - $fee;

        if ($user->seller_balance < $request->amount) {
            return back()->with('error', 'Insufficient seller balance.');
        }

        DB::transaction(function () use ($user, $request, $fee, $net) {
            $user->decrement('seller_balance', $request->amount);
            SellerWithdrawal::create([
                'user_id'         => $user->id,
                'amount'          => $request->amount,
                'fee'             => $fee,
                'net_amount'      => $net,
                'account_details' => $request->account_details,
                'status'          => 'pending',
            ]);
        });

        return back()->with('success', 'Withdrawal request submitted.');
    }

    // ── My purchases ────────────────────────────────────────────────────────

    public function myPurchases()
    {
        $currency = optional(Setting::first())->website_currency ?? '';

        // Seller account purchases
        $sellerPurchases = SellerAccount::with('product.user')
            ->where('buyer_id', Auth::id())
            ->get()
            ->map(fn($a) => [
                'type'        => 'seller',
                'title'       => $a->product->title ?? '—',
                'category'    => $a->product->category ?? '',
                'credentials' => $a->details,
                'seller'      => optional($a->product->user)->fname . ' ' . optional($a->product->user)->lname,
                'price'       => $a->product->price ?? 0,
                'date'        => $a->created_at,
            ]);

        // Admin account purchases
        $adminPurchases = \App\Models\AccountOrderItem::with(['product.productCategory', 'productDetail', 'accountOrder'])
            ->whereHas('accountOrder', fn($q) => $q->where('user_id', Auth::id()))
            ->get()
            ->map(fn($item) => [
                'type'        => 'admin',
                'title'       => $item->product->name ?? '—',
                'category'    => optional($item->product->productCategory)->name ?? '',
                'credentials' => $item->productDetail->details ?? '—',
                'seller'      => 'Admin',
                'price'       => $item->price,
                'date'        => $item->created_at,
            ]);

        $purchases = $sellerPurchases->merge($adminPurchases)
            ->sortByDesc('date')->values();

        return view('frontend.marketplace.purchases', [
            'title'     => 'My Purchases',
            'purchases' => $purchases,
            'currency'  => $currency,
        ]);
    }

    // ── Helper ──────────────────────────────────────────────────────────────

    private function requireSeller()
    {
        if (!Auth::user()->is_seller) {
            abort(403, 'Seller access required.');
        }
    }
}
