<?php

namespace App\Http\Controllers;

use App\Models\Frame;
use App\Models\FrameCategory;
use App\Models\FrameSubCategory;
use App\Models\Lens;
use App\Models\LensCategory;
use App\Models\LensSubCategory;
use App\Models\Order;
use App\Models\Package;
use App\Models\PaymentTransaction;
use App\Models\Subscription;
use App\Models\User;
use App\Models\VendorProfile;
use App\Services\OrderService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;

class VendorWebController extends Controller
{
    public function showLogin()
    {
        if (Auth::check() && Auth::user()->isVendor()) {
            return redirect()->route('vendor.dashboard');
        }
        return view('vendor.login');
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required',
            'password' => 'required',
        ]);

        $credentials = ['password' => $request->password, 'role' => 'vendor'];
        if (filter_var($request->email, FILTER_VALIDATE_EMAIL)) {
            $credentials['email'] = $request->email;
        } else {
            $credentials['phone'] = $request->email;
        }

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();
            return redirect()->route('vendor.dashboard');
        }

        return back()->withErrors(['email' => 'Invalid vendor login credentials.']);
    }

    public function dashboard()
    {
        $user = Auth::user();
        $totalFrames = Frame::where('vendor_id', $user->id)->count();
        $totalLenses = Lens::where('vendor_id', $user->id)->count();
        $totalOrders = Order::where('vendor_id', $user->id)->count();
        $pendingOrders = Order::where('vendor_id', $user->id)->whereIn('status', ['pending', 'confirmed'])->count();
        $lowStockItems = Frame::where('vendor_id', $user->id)->whereColumn('stock_quantity', '<=', 'low_stock_threshold')->count()
            + Lens::where('vendor_id', $user->id)->whereColumn('stock_quantity', '<=', 'low_stock_threshold')->count();
        $activeSubscription = $user->activeSubscription ? $user->activeSubscription->load('package') : null;
        $recentFrames = Frame::where('vendor_id', $user->id)->with(['category', 'subCategory'])->latest()->take(6)->get();

        return view('vendor.dashboard', compact('totalFrames', 'totalLenses', 'totalOrders', 'pendingOrders', 'lowStockItems', 'activeSubscription', 'recentFrames'));
    }

    public function frames()
    {
        $user = Auth::user();
        $frames = Frame::where('vendor_id', $user->id)->with(['category', 'subCategory'])->latest()->paginate(15);
        $categories = FrameCategory::where('vendor_id', $user->id)->orWhereNull('vendor_id')->with('subCategories')->get();

        return view('vendor.frames', compact('frames', 'categories'));
    }

    public function storeFrame(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'category_id' => 'nullable|exists:frame_categories,id',
            'sub_category_id' => 'nullable|exists:frame_sub_categories,id',
            'price' => 'required|numeric|min:0',
            'stock_quantity' => 'nullable|integer|min:0',
            'low_stock_threshold' => 'nullable|integer|min:0',
            'size' => 'nullable|string',
            'color' => 'nullable|string',
            'shape' => 'nullable|string',
            'rim_type' => 'nullable|string',
            'gender' => 'nullable|string',
            'description' => 'nullable|string',
            'images.*' => 'nullable|image|max:10240',
            'tryon_image' => 'nullable|image|max:10240',
        ]);

        $imageUrls = [];
        if ($request->hasFile('images')) {
            foreach ($request->file('images') as $file) {
                $path = $file->store('frames', 'public');
                $imageUrls[] = url('storage/' . $path);
            }
        }

        $tryonUrl = null;
        if ($request->hasFile('tryon_image')) {
            $path = $request->file('tryon_image')->store('tryon_frames', 'public');
            $tryonUrl = url('storage/' . $path);
        }

        Frame::create([
            'vendor_id' => Auth::id(),
            'category_id' => $request->category_id,
            'sub_category_id' => $request->sub_category_id,
            'name' => $request->name,
            'description' => $request->description,
            'price' => $request->price,
            'stock_quantity' => $request->input('stock_quantity', 0),
            'low_stock_threshold' => $request->input('low_stock_threshold', 5),
            'size' => $request->size,
            'color' => $request->color,
            'shape' => $request->shape,
            'rim_type' => $request->rim_type,
            'gender' => $request->gender,
            'images' => $imageUrls,
            'tryon_image_url' => $tryonUrl,
            'is_active' => true,
        ]);

        return back()->with('success', 'Frame added to catalog successfully!');
    }

    public function deleteFrame($id)
    {
        $frame = Frame::where('vendor_id', Auth::id())->findOrFail($id);
        $frame->delete();

        return back()->with('success', 'Frame removed.');
    }

    public function lenses()
    {
        $user = Auth::user();
        $lenses = Lens::where('vendor_id', $user->id)->with(['category', 'subCategory'])->latest()->paginate(15);
        $categories = LensCategory::where('vendor_id', $user->id)->orWhereNull('vendor_id')->with('subCategories')->get();

        return view('vendor.lenses', compact('lenses', 'categories'));
    }

    public function storeLens(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'category_id' => 'nullable|exists:lens_categories,id',
            'sub_category_id' => 'nullable|exists:lens_sub_categories,id',
            'price' => 'required|numeric|min:0',
            'stock_quantity' => 'nullable|integer|min:0',
            'low_stock_threshold' => 'nullable|integer|min:0',
            'size' => 'nullable|string',
            'color' => 'nullable|string',
            'lens_type' => 'nullable|string',
            'description' => 'nullable|string',
            'images.*' => 'nullable|image|max:10240',
            'tryon_image' => 'nullable|image|max:10240',
        ]);

        $imageUrls = [];
        if ($request->hasFile('images')) {
            foreach ($request->file('images') as $file) {
                $path = $file->store('lenses', 'public');
                $imageUrls[] = url('storage/' . $path);
            }
        }

        $tryonUrl = null;
        if ($request->hasFile('tryon_image')) {
            $path = $request->file('tryon_image')->store('tryon_lenses', 'public');
            $tryonUrl = url('storage/' . $path);
        }

        Lens::create([
            'vendor_id' => Auth::id(),
            'category_id' => $request->category_id,
            'sub_category_id' => $request->sub_category_id,
            'name' => $request->name,
            'description' => $request->description,
            'price' => $request->price,
            'stock_quantity' => $request->input('stock_quantity', 0),
            'low_stock_threshold' => $request->input('low_stock_threshold', 5),
            'size' => $request->size,
            'color' => $request->color,
            'lens_type' => $request->lens_type,
            'images' => $imageUrls,
            'tryon_image_url' => $tryonUrl,
            'is_active' => true,
        ]);

        return back()->with('success', 'Contact lens added to catalog successfully!');
    }

    public function deleteLens($id)
    {
        $lens = Lens::where('vendor_id', Auth::id())->findOrFail($id);
        $lens->delete();

        return back()->with('success', 'Lens removed.');
    }

    public function cutoutTool()
    {
        return view('vendor.cutout');
    }

    public function subscription()
    {
        $packages = Package::where('is_active', true)->orderBy('months')->get();
        $user = Auth::user();
        $activeSubscription = $user->activeSubscription ? $user->activeSubscription->load('package') : null;
        $transactions = PaymentTransaction::where('user_id', $user->id)->latest()->take(10)->get();

        return view('vendor.subscription', compact('packages', 'activeSubscription', 'transactions'));
    }

    public function profile()
    {
        $user = Auth::user()->load('vendorProfile');
        return view('vendor.profile', compact('user'));
    }

    public function updateProfile(Request $request)
    {
        $user = Auth::user();
        $request->validate([
            'name' => 'required|string|max:255',
            'vendor_name' => 'required|string|max:255',
            'phone' => 'required|string',
            'address' => 'nullable|string',
            'city' => 'nullable|string',
            'whatsapp_number' => 'nullable|string',
            'latitude' => 'nullable|numeric',
            'longitude' => 'nullable|numeric',
            'upi_id' => 'nullable|string|max:100',
            'upi_qr_code' => 'nullable|image|max:10240',
            'bank_name' => 'nullable|string|max:100',
            'account_number' => 'nullable|string|max:50',
            'ifsc_code' => 'nullable|string|max:20',
            'account_holder_name' => 'nullable|string|max:100',
            'custom_razorpay_key' => 'nullable|string|max:100',
            'payment_instructions' => 'nullable|string|max:500',
        ]);

        $user->update([
            'name' => $request->name,
            'phone' => $request->phone,
        ]);

        $profileData = [
            'vendor_name' => $request->vendor_name,
            'contact_person_name' => $request->name,
            'address' => $request->address,
            'city' => $request->city,
            'whatsapp_number' => $request->whatsapp_number,
            'latitude' => $request->latitude,
            'longitude' => $request->longitude,
            'upi_id' => $request->upi_id,
            'bank_name' => $request->bank_name,
            'account_number' => $request->account_number,
            'ifsc_code' => $request->ifsc_code,
            'account_holder_name' => $request->account_holder_name,
            'custom_razorpay_key' => $request->custom_razorpay_key,
            'payment_instructions' => $request->payment_instructions,
        ];

        // Handle UPI QR Code Image Upload
        if ($request->hasFile('upi_qr_code')) {
            $path = $request->file('upi_qr_code')->store('vendor_qrs', 'public');
            $profileData['upi_qr_code'] = url('storage/' . $path);
        }

        if ($request->hasFile('store_logo')) {
            $path = $request->file('store_logo')->store('store_logos', 'public');
            $profileData['store_logo'] = url('storage/' . $path);
        }

        if ($request->filled('opening_time')) {
            $profileData['opening_time'] = $request->opening_time;
        }
        if ($request->filled('closing_time')) {
            $profileData['closing_time'] = $request->closing_time;
        }
        if ($request->filled('working_days')) {
            $profileData['working_days'] = $request->working_days;
        }

        $user->vendorProfile()->updateOrCreate(
            ['user_id' => $user->id],
            $profileData
        );

        return back()->with('success', 'Store profile, timings & payment settings saved successfully! 💳');
    }

    public function banners()
    {
        $banners = \App\Models\VendorBanner::where('vendor_id', Auth::id())->orderBy('sort_order')->get();
        return view('vendor.banners', compact('banners'));
    }

    public function storeBanner(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'image' => 'required|image|max:10240',
            'link_url' => 'nullable|string',
        ]);

        $path = $request->file('image')->store('vendor_banners', 'public');

        \App\Models\VendorBanner::create([
            'vendor_id' => Auth::id(),
            'title' => $request->title,
            'image_url' => url('storage/' . $path),
            'link_url' => $request->link_url,
            'is_active' => true,
        ]);

        return back()->with('success', 'Store banner uploaded successfully! 🎉');
    }

    public function deleteBanner($id)
    {
        $banner = \App\Models\VendorBanner::where('vendor_id', Auth::id())->findOrFail($id);
        $banner->delete();
        return back()->with('success', 'Banner removed.');
    }

    public function offers()
    {
        $offers = \App\Models\VendorOffer::where('vendor_id', Auth::id())->latest()->get();
        return view('vendor.offers', compact('offers'));
    }

    public function storeOffer(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'coupon_code' => 'nullable|string|max:50',
            'discount_type' => 'required|in:percentage,flat',
            'discount_value' => 'required|numeric|min:0',
            'description' => 'nullable|string',
            'valid_until' => 'nullable|date',
        ]);

        \App\Models\VendorOffer::create([
            'vendor_id' => Auth::id(),
            'title' => $request->title,
            'coupon_code' => $request->coupon_code,
            'discount_type' => $request->discount_type,
            'discount_value' => $request->discount_value,
            'description' => $request->description,
            'valid_until' => $request->valid_until,
            'is_active' => true,
        ]);

        return back()->with('success', 'Store discount offer published! 🏷️');
    }

    public function deleteOffer($id)
    {
        $offer = \App\Models\VendorOffer::where('vendor_id', Auth::id())->findOrFail($id);
        $offer->delete();
        return back()->with('success', 'Offer deleted.');
    }

    public function events()
    {
        $events = \App\Models\VendorEvent::where('vendor_id', Auth::id())->latest()->get();
        return view('vendor.events', compact('events'));
    }

    public function storeEvent(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'event_type' => 'required|in:sale,event,exhibition,free_checkup,clearance',
            'banner' => 'nullable|image|max:10240',
            'description' => 'required|string',
            'discount_details' => 'nullable|string',
            'location' => 'nullable|string',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
        ]);

        $bannerImage = null;
        if ($request->hasFile('banner')) {
            $path = $request->file('banner')->store('vendor_events', 'public');
            $bannerImage = url('storage/' . $path);
        }

        \App\Models\VendorEvent::create([
            'vendor_id' => Auth::id(),
            'title' => $request->title,
            'event_type' => $request->event_type,
            'banner_image' => $bannerImage,
            'description' => $request->description,
            'discount_details' => $request->discount_details,
            'location' => $request->location ?? Auth::user()->vendorProfile?->address,
            'start_date' => $request->start_date,
            'end_date' => $request->end_date,
            'is_active' => true,
        ]);

        return back()->with('success', 'Store Sale / Event published successfully! 🎪🏷️');
    }

    public function deleteEvent($id)
    {
        $event = \App\Models\VendorEvent::where('vendor_id', Auth::id())->findOrFail($id);
        $event->delete();
        return back()->with('success', 'Event deleted.');
    }

    public function notifications()
    {
        $sentNotifications = \App\Models\AppNotification::where('sender_id', Auth::id())->latest()->get();
        $adminAnnouncements = \App\Models\AppNotification::where('sender_role', 'superadmin')
            ->whereIn('target_audience', ['all_vendors', 'both'])
            ->latest()
            ->take(15)
            ->get();

        return view('vendor.notifications', compact('sentNotifications', 'adminAnnouncements'));
    }

    public function sendNotification(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'message' => 'required|string|max:1000',
            'image' => 'nullable|image|max:10240',
        ]);

        $imageUrl = null;
        if ($request->hasFile('image')) {
            $path = $request->file('image')->store('notifications', 'public');
            $imageUrl = url('storage/' . $path);
        }

        \App\Models\AppNotification::create([
            'sender_id' => Auth::id(),
            'sender_role' => 'vendor',
            'target_audience' => 'all_users', // vendor sends to customers
            'title' => $request->title,
            'message' => $request->message,
            'image_url' => $imageUrl,
        ]);

        return back()->with('success', 'Push notification sent to all customers! 📢');
    }

    public function customers()
    {
        $vendorId = Auth::id();
        $customers = User::where('role', 'customer')
            ->whereHas('customerOrders', fn ($query) => $query->where('vendor_id', $vendorId))
            ->withCount(['customerOrders as orders_count' => fn ($query) => $query->where('vendor_id', $vendorId)])
            ->withSum(['customerOrders as total_spent' => fn ($query) => $query->where('vendor_id', $vendorId)->where('status', '!=', 'cancelled')], 'total')
            ->latest()
            ->paginate(20);

        return view('vendor.customers', compact('customers'));
    }

    public function orders(Request $request)
    {
        $query = Order::where('vendor_id', Auth::id())->with(['items', 'customer'])->latest('ordered_at');

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(fn ($q) => $q->where('order_number', 'like', "%{$search}%")
                ->orWhere('customer_name', 'like', "%{$search}%")
                ->orWhere('customer_phone', 'like', "%{$search}%"));
        }

        $orders = $query->paginate(20)->withQueryString();
        $customers = User::where('role', 'customer')->orderBy('name')->get(['id', 'name', 'phone', 'email']);
        $frames = Frame::where('vendor_id', Auth::id())->where('is_active', true)->orderBy('name')->get();
        $lenses = Lens::where('vendor_id', Auth::id())->where('is_active', true)->orderBy('name')->get();

        return view('vendor.orders', compact('orders', 'customers', 'frames', 'lenses'));
    }

    public function storeOrder(Request $request, OrderService $orders)
    {
        $data = $request->validate([
            'customer_id' => 'nullable|exists:users,id',
            'customer_name' => 'nullable|string|max:255',
            'customer_phone' => 'nullable|string|max:30',
            'customer_email' => 'nullable|email|max:255',
            'billing_address' => 'nullable|string|max:1000',
            'payment_status' => 'required|in:unpaid,partial,paid',
            'discount_amount' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string|max:1000',
            'items' => 'required|array|min:1',
            'items.*.product' => ['required', 'regex:/^(frame|lens):\d+$/'],
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.unit_price' => 'nullable|numeric|min:0',
        ]);

        $data['items'] = collect($data['items'])->map(function ($item) {
            [$type, $id] = explode(':', $item['product'], 2);
            return [
                'item_type' => $type,
                'item_id' => (int) $id,
                'quantity' => (int) $item['quantity'],
                'unit_price' => $item['unit_price'] ?? null,
            ];
        })->all();

        $order = $orders->create(Auth::user(), $data);

        return redirect()->route('vendor.orders')->with('success', "Order {$order->order_number} created and stock updated.");
    }

    public function updateOrder(Request $request, int $id, OrderService $orders)
    {
        $data = $request->validate([
            'status' => 'required|in:pending,confirmed,ready,completed,cancelled',
            'payment_status' => 'required|in:unpaid,partial,paid,refunded',
        ]);
        $order = Order::where('vendor_id', Auth::id())->findOrFail($id);
        $orders->updateStatus($order, $data['status'], $data['payment_status']);

        return back()->with('success', "Order {$order->order_number} updated.");
    }

    public function stock()
    {
        $frames = Frame::where('vendor_id', Auth::id())->orderBy('name')->get();
        $lenses = Lens::where('vendor_id', Auth::id())->orderBy('name')->get();

        return view('vendor.stock', compact('frames', 'lenses'));
    }

    public function updateStock(Request $request, string $type, int $id)
    {
        $data = $request->validate([
            'stock_quantity' => 'required|integer|min:0',
            'low_stock_threshold' => 'required|integer|min:0',
        ]);
        $product = $this->vendorProduct($type, $id);
        $product->update($data);

        return back()->with('success', "Stock updated for {$product->name}.");
    }

    public function toggleProduct(string $type, int $id)
    {
        $product = $this->vendorProduct($type, $id);
        $product->update(['is_active' => !$product->is_active]);

        return back()->with('success', "{$product->name} is now " . ($product->is_active ? 'enabled.' : 'disabled.'));
    }

    public function bills()
    {
        $bills = Order::where('vendor_id', Auth::id())
            ->where('status', '!=', 'cancelled')
            ->with('customer')
            ->latest('ordered_at')
            ->paginate(20);

        return view('vendor.bills', compact('bills'));
    }

    public function bill(int $id)
    {
        $order = Order::where('vendor_id', Auth::id())->with(['items', 'customer', 'vendor.vendorProfile'])->findOrFail($id);

        return view('vendor.bill', compact('order'));
    }

    private function vendorProduct(string $type, int $id): Frame|Lens
    {
        abort_unless(in_array($type, ['frame', 'lens'], true), 404);
        $model = $type === 'frame' ? Frame::class : Lens::class;

        return $model::where('vendor_id', Auth::id())->findOrFail($id);
    }

    public function logout(Request $request)
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('vendor.login');
    }
}
