<?php
namespace App\Services;

use App\Utils\DateNormalizer;

class PaymentEligibilityService
{
    public function isCommissionEligible(array $payment, bool $requiresSepidar = false, bool $adjustmentMode = false): bool
    {
        return $this->resolveCommissionEligibility($payment, $requiresSepidar, $adjustmentMode)['eligible'];
    }

    public function resolveCommissionEligibility(array $payment, bool $requiresSepidar = false, bool $adjustmentMode = false): array
    {
        $amount = (float)($payment['amount'] ?? 0);
        if ($amount <= 0) {
            return $this->result(false, null, 'amount_not_positive');
        }
        if (!empty($payment['is_deleted_placeholder'])) {
            return $this->result(false, null, 'deleted_placeholder');
        }

        $refundStatus = strtoupper(trim((string)($payment['refund_status'] ?? 'NONE')));
        if ($refundStatus === 'FULL') {
            return $this->result(false, null, 'fully_refunded');
        }

        $commissionStatus = strtoupper(trim((string)($payment['commission_status'] ?? 'PENDING')));
        if (!$adjustmentMode && in_array($commissionStatus, ['PAID', 'VOID', 'CLAWED_BACK'], true)) {
            return $this->result(false, null, 'commission_status_' . strtolower($commissionStatus));
        }

        if ($this->isSudranGateway($payment)) {
            return $this->result(false, null, 'sudran_gateway_payment');
        }

        if ($requiresSepidar) {
            $financeStatus = strtoupper(trim((string)($payment['finance_status'] ?? 'NONE')));
            if ($financeStatus !== 'SEPIDAR_REGISTERED') {
                return $this->result(false, null, 'sepidar_required');
            }
        }

        if ($this->isCheque($payment)) {
            $chequeStatus = strtolower(trim((string)($payment['cheque_status'] ?? 'pending')));
            $collectionStatus = strtolower(trim((string)($payment['cheque_collection_status'] ?? 'pending')));
            $collectionDate = $this->normalizeDate((string)($payment['cheque_collection_date'] ?? $payment['collection_date'] ?? ''));
            if ($chequeStatus !== 'approved') {
                return $this->result(false, null, 'cheque_not_approved');
            }
            if ($collectionStatus !== 'collected' || $collectionDate === null) {
                return $this->result(false, null, 'cheque_not_collected');
            }
            return $this->result(true, $collectionDate, 'eligible_cheque_collected');
        }

        $effectiveDate = $this->normalizeDate((string)($payment['effective_date'] ?? ''))
            ?: $this->normalizeDate((string)($payment['deposit_date'] ?? ''))
            ?: $this->normalizeDate((string)($payment['payment_date'] ?? ''));
        if ($effectiveDate === null) {
            return $this->result(false, null, 'effective_date_missing');
        }

        return $this->result(true, $effectiveDate, 'eligible_non_cheque');
    }

    public function isCheque(array $payment): bool
    {
        $chequeStatus = strtolower(trim((string)($payment['cheque_status'] ?? 'not_cheque')));
        $collectionStatus = strtolower(trim((string)($payment['cheque_collection_status'] ?? 'not_cheque')));
        $rawMethod = (string)(($payment['method'] ?? '') ?: ($payment['payment_method'] ?? ''));
        $method = strtolower(trim($rawMethod));
        $methodIsCheque = strpos($method, 'check') !== false
            || strpos($method, 'cheque') !== false
            || strpos($rawMethod, 'چک') !== false;
        if (trim($rawMethod) !== '') {
            return $methodIsCheque;
        }
        return $chequeStatus !== 'not_cheque' || $collectionStatus !== 'not_cheque';
    }

    private function isSudranGateway(array $payment): bool
    {
        $method = trim((string)(($payment['method'] ?? '') ?: ($payment['payment_method'] ?? '')));
        $rawSnapshot = (string)($payment['raw_snapshot_json'] ?? '');
        $code = strtolower(preg_replace('/[\s\-\/]+/', '_', $method));
        $rawSnapshotLower = strtolower($rawSnapshot);
        return in_array($code, ['sudran_payment_gateway', 'sudran_gateway', 'soodran_payment_gateway', 'soodran_gateway', 'sodran_payment_gateway'], true)
            || strpos($method, 'سودران') !== false
            || strpos($rawSnapshotLower, 'sudran') !== false
            || strpos($rawSnapshotLower, 'soodran') !== false
            || strpos($rawSnapshotLower, 'sodran') !== false
            || strpos($rawSnapshot, 'سودران') !== false;
    }

    private function result(bool $eligible, ?string $effectiveDate, string $reason): array
    {
        return [
            'eligible' => $eligible,
            'effective_date' => $effectiveDate,
            'reason' => $reason,
        ];
    }

    private function normalizeDate(string $value): ?string
    {
        return DateNormalizer::normalizeGregorianOrJalaliDate($value);
    }
}
