<?php

namespace App\Services;

use App\Models\DeliveryMan;
use App\Models\Order;
use App\Models\RiderRevenueCollection;
use Illuminate\Support\Facades\DB;

class RiderWalletService
{
    public function accrueFromDeliveredOrder(Order $order, DeliveryMan $rider): void
    {
        $payment = $order->payment;
        if (!$payment) {
            return;
        }

        $shippingCharge = (float) $order->shipping_charge;
        $commissionPercent = (float) $rider->platform_commission_percent;
        $riderShare = round($shippingCharge - ($shippingCharge * ($commissionPercent / 100)), 2);

        if ($payment->payment_method === 'cod') {
            $orderAmount = (float) $order->amount;
            $productPortion = max(0, round($orderAmount - $shippingCharge, 2));
            $commissionDue = round($shippingCharge * ($commissionPercent / 100), 2);

            $rider->due_product_amount = round((float) $rider->due_product_amount + $productPortion, 2);
            $rider->due_commission_amount = round((float) $rider->due_commission_amount + $commissionDue, 2);
            $rider->save();

            return;
        }

        // Online / digital payment — rider payout tracked in wallet (admin withdraws from web).
        $rider->digital_wallet_balance = round((float) ($rider->digital_wallet_balance ?? 0) + $riderShare, 2);
        $rider->save();
    }

    public function riderShareForOrder(Order $order, DeliveryMan $rider): float
    {
        $shippingCharge = (float) $order->shipping_charge;
        $commissionPercent = (float) $rider->platform_commission_percent;

        return round($shippingCharge - ($shippingCharge * ($commissionPercent / 100)), 2);
    }

    public function walletSummary(DeliveryMan $rider): array
    {
        $product = round((float) $rider->due_product_amount, 2);
        $commission = round((float) $rider->due_commission_amount, 2);

        return [
            'due_product_amount' => $product,
            'due_commission_amount' => $commission,
            'total_due_to_platform' => round($product + $commission, 2),
            'digital_wallet_balance' => round((float) ($rider->digital_wallet_balance ?? 0), 2),
        ];
    }

    public function completeDigitalPayout(DeliveryMan $rider, float $amount, ?int $adminUserId = null): array
    {
        $balance = round((float) ($rider->digital_wallet_balance ?? 0), 2);
        if ($balance <= 0) {
            return ['ok' => false, 'message' => 'No digital wallet balance to pay out.'];
        }

        $pay = $amount > 0 ? min($amount, $balance) : $balance;

        $rider->digital_wallet_balance = round($balance - $pay, 2);
        $rider->save();

        return [
            'ok' => true,
            'message' => 'Paid ৳' . number_format($pay, 2) . ' to rider. Remaining wallet: ৳' . number_format((float) $rider->digital_wallet_balance, 2),
            'paid_amount' => $pay,
        ];
    }

    public function initiateCollection(DeliveryMan $rider, ?int $adminUserId = null, ?string $note = null): array
    {
        $product = round((float) $rider->due_product_amount, 2);
        $commission = round((float) $rider->due_commission_amount, 2);
        $total = round($product + $commission, 2);

        if ($total <= 0) {
            return ['ok' => false, 'message' => 'This rider has no balance due to the platform.'];
        }

        if (!$rider->email) {
            return ['ok' => false, 'message' => 'Rider has no email on file. Add an email before collecting revenue.'];
        }

        RiderRevenueCollection::where('delivery_man_id', $rider->id)
            ->where('status', 'pending')
            ->update(['status' => 'cancelled']);

        $otp = (string) random_int(100000, 999999);

        $collection = RiderRevenueCollection::create([
            'delivery_man_id' => $rider->id,
            'product_amount' => $product,
            'commission_amount' => $commission,
            'total_amount' => $total,
            'status' => 'pending',
            'otp' => $otp,
            'otp_expires_at' => now()->addMinutes(15),
            'collected_by' => $adminUserId,
            'note' => $note,
        ]);

        $site = \App\Models\GeneralSetting::where('status', 1)->first();
        $siteName = $site?->name ?? config('app.name');
        $message = "Revenue collection OTP for {$rider->name}: {$otp}. Product due: ৳{$product}, Commission due: ৳{$commission}, Total: ৳{$total}. Valid 15 minutes.";

        app(SmsService::class)->sendEmailToAddress(
            $rider->email,
            $rider->name,
            $message,
            $otp,
            "Revenue collection OTP — {$siteName}"
        );

        return [
            'ok' => true,
            'message' => 'OTP sent to rider email. Enter it below to complete collection.',
            'collection_id' => $collection->id,
            'email_hint' => $this->maskEmail($rider->email),
        ];
    }

    public function completeCollection(DeliveryMan $rider, string $otp, ?int $adminUserId = null): array
    {
        $collection = RiderRevenueCollection::where('delivery_man_id', $rider->id)
            ->where('status', 'pending')
            ->latest()
            ->first();

        if (!$collection) {
            return ['ok' => false, 'message' => 'No pending collection. Send OTP first.'];
        }

        if ($collection->otp_expires_at && $collection->otp_expires_at->isPast()) {
            $collection->update(['status' => 'cancelled']);
            return ['ok' => false, 'message' => 'OTP expired. Please send a new OTP.'];
        }

        if ((string) $collection->otp !== trim($otp)) {
            return ['ok' => false, 'message' => 'Invalid OTP.'];
        }

        return DB::transaction(function () use ($rider, $collection, $adminUserId) {
            $collection->update([
                'status' => 'completed',
                'collected_at' => now(),
                'collected_by' => $adminUserId ?? $collection->collected_by,
            ]);

            $rider->update([
                'due_product_amount' => 0,
                'due_commission_amount' => 0,
            ]);

            return [
                'ok' => true,
                'message' => 'Revenue collected. Rider balance reset to ৳0.',
                'collection' => $collection->fresh(),
            ];
        });
    }

    protected function maskEmail(string $email): string
    {
        $parts = explode('@', $email);
        if (count($parts) < 2) {
            return $email;
        }
        $name = $parts[0];
        return substr($name, 0, 2) . str_repeat('*', max(0, strlen($name) - 2)) . '@' . $parts[1];
    }
}
