<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Courier;
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 CourierController extends Controller
{
    public function index()
    {
        $couriers = Courier::with('zone')->orderBy('name')->get();
        $total = $couriers->count();
        $active = $couriers->where('is_active', true)->count();
        $inactive = $total - $active;
        $totalBalance = $couriers->sum('wallet_balance');

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

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

    public function show(Courier $courier)
    {
        $courier->load('zone');

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

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

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

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

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

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

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

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

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

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

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

        if ($courier->wallet_balance >= (float) $data['amount']) {
            app(\App\Services\WalletService::class)->debitCourier(
                $courier,
                (float) $data['amount'],
                'Retiro admin',
                null,
                $request->user()->id,
                'payout'
            );

            $courier->update([
                'wallet_withdrawn' => $courier->wallet_withdrawn + (float) $data['amount'],
            ]);
        }

        return redirect()
            ->route('admin.couriers.wallet', $courier)
            ->with('success', 'Retiro registrado.');
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'zone_id' => 'nullable|exists:zones,id',
            'name' => 'required|string|max:255',
            'phone' => 'nullable|string|max:50',
            'email' => 'nullable|email|max:255',
            'vehicle_type' => 'nullable|string|max:100',
            'notes' => 'nullable|string',
            'wallet_balance' => '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). wallet_balance is NOT nullable in DB.
        // Start 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;

        $courier = Courier::create($data);

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

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

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

    public function edit(Courier $courier)
    {
        $courierUser = User::where('courier_id', $courier->id)->first();

        return view('admin.couriers.edit', [
            'courier' => $courier,
            'zones' => Zone::orderBy('name')->get(),
            'courierUser' => $courierUser,
        ]);
    }

    public function update(Request $request, Courier $courier)
    {
        $courierUser = User::where('courier_id', $courier->id)->first();

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

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

        $courier->update($data);

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

        if (!empty($data['wallet_payout'])) {
            if ($courier->wallet_balance >= $data['wallet_payout']) {
                app(WalletService::class)->debitCourier(
                    $courier,
                    (float) $data['wallet_payout'],
                    'Retiro admin',
                    null,
                    $request->user()->id,
                    'payout'
                );
                $courier->update([
                    'wallet_withdrawn' => $courier->wallet_withdrawn + (float) $data['wallet_payout'],
                ]);
            }
        }

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

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

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

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

    public function destroy(Courier $courier)
    {
        $courier->delete();

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

    public function forceOnline(Request $request, Courier $courier)
    {
        $courier->update([
            'is_online' => true,
        ]);

        return redirect()
            ->back()
            ->with('success', 'Repartidor marcado como en línea.');
    }
}
