<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Restaurant;
use App\Models\User;
use App\Models\Zone;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Services\WalletService;
use Illuminate\Validation\Rule;

class RestaurantController extends Controller
{
    public function index()
    {
        $restaurants = Restaurant::with('zone')->orderBy('name')->get();
        $total = $restaurants->count();
        $active = $restaurants->where('is_active', true)->count();
        $inactive = $total - $active;
        $totalBalance = $restaurants->sum('wallet_balance');

        return view('admin.restaurants.index', [
            'restaurants' => $restaurants,
            'stats' => [
                'total' => $total,
                'active' => $active,
                'inactive' => $inactive,
                'balance' => $totalBalance,
            ],
        ]);
    }

    public function create()
    {
        return view('admin.restaurants.create', [
            'zones' => Zone::orderBy('name')->get(),
        ]);
    }

    public function show(Restaurant $restaurant)
    {
        $restaurant->load('zone');

        $deliveries = $restaurant->deliveries()->latest()->take(20)->get();
        $counts = [
            'pending' => $restaurant->deliveries()->where('status', 'pending')->count(),
            'confirmed' => $restaurant->deliveries()->where('status', \App\Models\Delivery::STATUS_CONFIRMED)->count(),
            'delivered' => $restaurant->deliveries()->where('status', \App\Models\Delivery::STATUS_DELIVERED)->count(),
            'total' => $restaurant->deliveries()->count(),
        ];

        $transactions = \App\Models\WalletTransaction::query()
            ->where('owner_type', 'restaurant')
            ->where('owner_id', $restaurant->id)
            ->latest()
            ->take(20)
            ->get();

        return view('admin.restaurants.show', [
            'restaurant' => $restaurant,
            'deliveries' => $deliveries,
            'counts' => $counts,
            'transactions' => $transactions,
        ]);
    }

    public function movements(Restaurant $restaurant)
    {
        $restaurant->load('zone');
        $transactions = \App\Models\WalletTransaction::query()
            ->where('owner_type', 'restaurant')
            ->where('owner_id', $restaurant->id)
            ->latest()
            ->paginate(15);

        return view('admin.restaurants.movements', [
            'restaurant' => $restaurant,
            'transactions' => $transactions,
        ]);
    }

    public function wallet(Restaurant $restaurant)
    {
        $restaurant->load('zone');
        $transactions = \App\Models\WalletTransaction::query()
            ->where('owner_type', 'restaurant')
            ->where('owner_id', $restaurant->id)
            ->latest()
            ->paginate(20);

        return view('admin.restaurants.wallet', [
            'restaurant' => $restaurant,
            'transactions' => $transactions,
        ]);
    }

    public function walletTopup(Request $request, Restaurant $restaurant)
    {
        $data = $request->validate([
            'amount' => 'required|numeric|min:0.01',
        ]);

        app(\App\Services\WalletService::class)->creditRestaurant(
            $restaurant,
            (float) $data['amount'],
            'Recarga admin',
            null,
            $request->user()->id
        );

        return redirect()
            ->route('admin.restaurants.wallet', $restaurant)
            ->with('success', 'Saldo recargado.');
    }

    public function walletCharge(Request $request, Restaurant $restaurant)
    {
        $data = $request->validate([
            'amount' => 'required|numeric|min:0.01',
        ]);

        app(\App\Services\WalletService::class)->debitRestaurant(
            $restaurant,
            (float) $data['amount'],
            'Descuento admin',
            null,
            $request->user()->id
        );

        return redirect()
            ->route('admin.restaurants.wallet', $restaurant)
            ->with('success', 'Saldo descontado.');
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'zone_id' => 'nullable|exists:zones,id',
            'name' => 'required|string|max:255',
            'contact_name' => 'nullable|string|max:255',
            'phone' => 'nullable|string|max:50',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string|max:255',
            'lat' => 'nullable|numeric',
            'lng' => 'nullable|numeric',
            'notes' => 'nullable|string',
            'wallet_balance' => 'nullable|numeric|min:0',
            'delivery_fee' => 'nullable|numeric|min:0',
            'is_active' => 'nullable|boolean',
            'login_email' => 'nullable|email|max:255|unique:users,email',
            'login_password' => 'nullable|string|min:6',
        ]);

        $data['is_active'] = $request->boolean('is_active');

        // The form can submit empty strings (converted to null). These columns are NOT nullable in DB.
        // Keep the database values consistent: start wallet at 0 and record any initial topup as a wallet movement.
        $initialWallet = (float) ($data['wallet_balance'] ?? 0);
        unset($data['wallet_balance']);
        $data['wallet_balance'] = 0;

        if (array_key_exists('delivery_fee', $data) && $data['delivery_fee'] === null) {
            unset($data['delivery_fee']); // Let DB default apply
        }

        $restaurant = Restaurant::create($data);

        if ($initialWallet > 0) {
            app(WalletService::class)->creditRestaurant(
                $restaurant,
                $initialWallet,
                'Saldo inicial',
                null,
                $request->user()->id
            );
        }

        if (!empty($data['login_email']) && !empty($data['login_password'])) {
            User::create([
                'name' => $restaurant->name,
                'email' => $data['login_email'],
                'password' => Hash::make($data['login_password']),
                'role' => 'restaurant',
                'restaurant_id' => $restaurant->id,
            ]);
        }

        return redirect()
            ->route('admin.restaurants.index')
            ->with('success', 'Restaurante creado correctamente.');
    }

    public function edit(Restaurant $restaurant)
    {
        $restaurantUser = User::where('restaurant_id', $restaurant->id)->first();

        return view('admin.restaurants.edit', [
            'restaurant' => $restaurant,
            'zones' => Zone::orderBy('name')->get(),
            'restaurantUser' => $restaurantUser,
        ]);
    }

    public function update(Request $request, Restaurant $restaurant)
    {
        $restaurantUser = User::where('restaurant_id', $restaurant->id)->first();

        $data = $request->validate([
            'zone_id' => 'nullable|exists:zones,id',
            'name' => 'required|string|max:255',
            'contact_name' => 'nullable|string|max:255',
            'phone' => 'nullable|string|max:50',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string|max:255',
            'lat' => 'nullable|numeric',
            'lng' => 'nullable|numeric',
            'notes' => 'nullable|string',
            'delivery_fee' => 'nullable|numeric|min:0',
            'wallet_topup' => 'nullable|numeric|min:0',
            'wallet_charge' => 'nullable|numeric|min:0',
            'is_active' => 'nullable|boolean',
            'login_email' => [
                'nullable',
                'email',
                'max:255',
                Rule::unique('users', 'email')->ignore($restaurantUser?->id),
            ],
            'login_password' => 'nullable|string|min:6',
        ]);

        $data['is_active'] = $request->boolean('is_active');

        $restaurant->update($data);

        if (!empty($data['wallet_topup'])) {
            app(WalletService::class)->creditRestaurant(
                $restaurant,
                (float) $data['wallet_topup'],
                'Recarga admin',
                null,
                $request->user()->id
            );
        }

        if (!empty($data['wallet_charge'])) {
            app(WalletService::class)->debitRestaurant(
                $restaurant,
                (float) $data['wallet_charge'],
                'Descuento admin',
                null,
                $request->user()->id
            );
        }

        if (!empty($data['login_email'])) {
            $user = User::where('restaurant_id', $restaurant->id)->first();

            if (!$user) {
                $user = User::where('email', $data['login_email'])->first();
            }

            if ($user) {
                $user->email = $data['login_email'];
                $user->name = $restaurant->name;
                $user->role = 'restaurant';
                $user->restaurant_id = $restaurant->id;
                if (!empty($data['login_password'])) {
                    $user->password = Hash::make($data['login_password']);
                }
                $user->save();
            } elseif (!empty($data['login_password'])) {
                User::create([
                    'name' => $restaurant->name,
                    'email' => $data['login_email'],
                    'password' => Hash::make($data['login_password']),
                    'role' => 'restaurant',
                    'restaurant_id' => $restaurant->id,
                ]);
            }
        }

        return redirect()
            ->route('admin.restaurants.index')
            ->with('success', 'Restaurante actualizado.');
    }

    public function destroy(Restaurant $restaurant)
    {
        $restaurant->delete();

        return redirect()
            ->route('admin.restaurants.index')
            ->with('success', 'Restaurante eliminado.');
    }
}
