<?php

namespace App\Modules\Addon\MigrateWisecp\Importers;

use App\Models\Order;
use Illuminate\Support\Str;

/**
 * PRC-1125 — WiseCP `checkouts` → procp `orders`.
 *
 * WiseCP FARKLARI:
 * - Temiz orders tablosu YOK; `checkouts` JSON basket kaydı. total/pmethod/invoice_id
 *   `data` JSON blob'unda → parse edilir (bozuk JSON → satır 'failed', taban izole eder).
 * - id bigint; order_number = checkout id.
 * - `orders.payment_method` bir ENUM → WiseCP gateway adı normalize edilir (aksi hâlde
 *   MySQL truncation — WHMCS addon'unda yakalanan aynı sınıf bug).
 */
class OrderImporter extends AbstractWisecpImporter
{
    public function sourceType(): string
    {
        return 'order';
    }

    protected function sourceTable(): string
    {
        return 'checkouts';
    }

    protected function importRow(object $row): ?int
    {
        $clientId = $this->ledger->map('client', $row->user_id);
        if ($clientId === null) {
            $this->report->warn(
                $this->sourceType(),
                "Sipariş #{$row->id}: client (user_id={$row->user_id}) import edilmemiş → atlandı."
            );

            return null;
        }

        $data = json_decode((string) ($row->data ?? ''), true);
        if (! is_array($data)) {
            $data = [];
        }

        // Fatura FK opsiyonel — data.invoice_id ledger'da eşleşiyorsa bağla.
        $invoiceId = null;
        $wisecpInvoiceId = (int) ($data['invoice_id'] ?? 0);
        if ($wisecpInvoiceId > 0) {
            $invoiceId = $this->ledger->map('invoice', $wisecpInvoiceId);
        }

        $amount = (float) ($data['total'] ?? 0);

        $order = Order::create([
            'uuid' => (string) Str::uuid(),
            'order_number' => (string) $row->id,
            'client_id' => $clientId,
            'amount' => $amount,
            'total' => $amount,
            'invoice_id' => $invoiceId,
            'status' => $this->mapStatus((string) ($row->status ?? '')),
            'payment_method' => $this->mapPaymentMethod($data['pmethod'] ?? null),
            'ordered_at' => $this->normalizeDate($row->cdate ?? null),
            // Göç edilen veri için otomatik yan-etkileri kapat.
            'send_email' => false,
            'create_invoice' => false,
        ]);

        return $order->id;
    }

    /** WiseCP checkout status → procp orders.status enum. Bilinmeyen → pending. */
    private function mapStatus(string $status): string
    {
        return match (strtolower(trim($status))) {
            'paid', 'completed' => 'paid',
            'accepted', 'active' => 'accepted',
            'cancelled', 'canceled', 'fraud' => 'cancelled',
            'refunded' => 'refunded',
            default => 'pending',
        };
    }

    /**
     * WiseCP gateway adını procp `orders.payment_method` ENUM'una
     * ('credit_card','bank_transfer','paypal','manual') normalize et. 'Balance'
     * (bakiye ödemesi) → manual. Bilinmeyen → null (kolon nullable).
     */
    private function mapPaymentMethod(?string $pmethod): ?string
    {
        $key = strtolower(trim((string) $pmethod));
        if ($key === '' || $key === 'none') {
            return null;
        }

        if (in_array($key, ['credit_card', 'bank_transfer', 'paypal', 'manual'], true)) {
            return $key;
        }

        return match (true) {
            str_contains($key, 'paypal') => 'paypal',
            str_contains($key, 'balance') => 'manual',
            str_contains($key, 'bank'), str_contains($key, 'transfer'),
                str_contains($key, 'wire'), str_contains($key, 'eft'),
                str_contains($key, 'havale') => 'bank_transfer',
            str_contains($key, 'card'), str_contains($key, 'stripe'),
                str_contains($key, 'iyzico'), str_contains($key, 'payu'),
                str_contains($key, 'garanti'), str_contains($key, 'nestpay') => 'credit_card',
            default => null,
        };
    }

    private function normalizeDate(?string $date): ?string
    {
        $d = trim((string) ($date ?? ''));
        if ($d === '' || str_starts_with($d, '0000-00-00') || str_starts_with($d, '1881-05-19')) {
            return null;
        }

        return $d;
    }
}
