<?php

namespace App\Services\Customer;

use App\Models\BusinessSetting;
use App\Models\Order;
use App\Models\User;

class CustomerCodRestrictionService
{
    private const ENABLE_KEY = 'risk_based_cod_restriction_status';
    private const THRESHOLD_KEY = 'risk_based_cod_restriction_threshold';
    private const MESSAGE_KEY = 'risk_based_cod_restriction_message';
    private const DEFAULT_THRESHOLD = 70;
    private const DEFAULT_MESSAGE = 'Cash on Delivery and offline payment are not available for this account. Please complete checkout using full payment.';
    private const FINALIZED_STATUSES = ['delivered', 'returned', 'canceled', 'failed'];
    private const RISKY_STATUSES = ['returned', 'canceled', 'failed'];

    public function settings(): array
    {
        try {
            $settings = BusinessSetting::query()
                ->whereIn('key', [self::ENABLE_KEY, self::THRESHOLD_KEY, self::MESSAGE_KEY])
                ->pluck('value', 'key')
                ->toArray();
        } catch (\Throwable $e) {
            return [
                'enabled' => false,
                'threshold' => self::DEFAULT_THRESHOLD,
                'message' => self::DEFAULT_MESSAGE,
            ];
        }

        $threshold = (float) ($settings[self::THRESHOLD_KEY] ?? self::DEFAULT_THRESHOLD);
        $threshold = max(0, min(100, $threshold));

        return [
            'enabled' => (int) ($settings[self::ENABLE_KEY] ?? 0) === 1,
            'threshold' => $threshold,
            'message' => $this->resolveMessage($settings[self::MESSAGE_KEY] ?? null),
        ];
    }

    public function payloadFor(?User $user): array
    {
        try {
            $settings = $this->settings();
        } catch (\Throwable $e) {
            $settings = ['enabled' => false, 'threshold' => self::DEFAULT_THRESHOLD, 'message' => self::DEFAULT_MESSAGE];
        }

        $finalizedOrders = 0;
        $riskyOrders = 0;
        $riskRatio = 0.0;

        if ($user && $user->id) {
            try {
                $baseQuery = Order::query()
                    ->where('user_id', $user->id)
                    ->where('is_guest', 0)
                    ->whereIn('order_status', self::FINALIZED_STATUSES);

                $finalizedOrders = (clone $baseQuery)->count();
                $riskyOrders = (clone $baseQuery)->whereIn('order_status', self::RISKY_STATUSES)->count();
                $riskRatio = $finalizedOrders > 0 ? round(($riskyOrders / $finalizedOrders) * 100, 2) : 0.0;
            } catch (\Throwable $e) {
                $finalizedOrders = 0;
                $riskyOrders = 0;
                $riskRatio = 0.0;
            }
        }

        $isRestricted = ($settings['enabled'] ?? false) && $user && $riskRatio >= ($settings['threshold'] ?? self::DEFAULT_THRESHOLD);

        return [
            'enabled' => $settings['enabled'],
            'is_restricted' => (bool) $isRestricted,
            'full_payment_only' => (bool) $isRestricted,
            'threshold' => $settings['threshold'],
            'risk_ratio' => $riskRatio,
            'risky_orders' => $riskyOrders,
            'finalized_orders' => $finalizedOrders,
            'message' => $settings['message'],
        ];
    }

    public function getRestrictionStatus(?User $user): array
    {
        return $this->payloadFor($user);
    }

    public function isRestricted(?User $user): bool
    {
        return (bool) data_get($this->payloadFor($user), 'is_restricted', false);
    }

    public static function defaultMessage(): string
    {
        return self::DEFAULT_MESSAGE;
    }

    private function resolveMessage(?string $message): string
    {
        $message = trim((string) $message);
        $normalized = strtolower($message);

        return !in_array($normalized, ['', '0', 'null', 'false'], true)
            ? $message
            : self::DEFAULT_MESSAGE;
    }
}
