<?php

namespace App\Modules\Addon\MigrateWisecp\Importers;

use App\Models\ClientDomain;
use App\Modules\Addon\MigrateWisecp\Services\WisecpSourceConnection;
use Illuminate\Support\Facades\DB;

/**
 * PRC-1125 — WiseCP `users_products` WHERE type='domain' → procp `ClientDomain`.
 *
 * WiseCP FARKLARI:
 * - Domain ve service AYNI `users_products` tablosunda; `type` discriminator.
 *   sourceQuery type='domain' filtreler.
 * - Domain adı `name` kolonunda. TLD adDAN çıkarılır (module-is-truth #2) → wisecp_tld_map.
 * - Registrar `module` kolonunda (ör. 'DomainNameAPI') — map'ten procp registrar'a çevrilir.
 * - Tarihler: cdate=oluşturma, duedate=bitiş, renewaldate=sonraki yenileme.
 */
class DomainImporter extends AbstractWisecpImporter
{
    public function sourceType(): string
    {
        return 'domain';
    }

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

    protected function sourceQuery()
    {
        return WisecpSourceConnection::table('users_products')->where('type', 'domain');
    }

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

            return null;
        }

        $domainName = strtolower(trim((string) $row->name));
        $tldStr = explode('.', $domainName, 2)[1] ?? '';
        if ($tldStr === '') {
            $this->report->warn(
                $this->sourceType(),
                "Domain #{$row->id} ('{$domainName}'): TLD çıkarılamadı → atlandı."
            );

            return null;
        }

        $tldKey = '.'.ltrim($tldStr, '.');
        $mapping = DB::table('wisecp_tld_map')
            ->where('wisecp_tld', $tldKey)
            ->first(['procp_tld_id', 'procp_registrar']);

        if ($mapping === null || $mapping->procp_tld_id === null) {
            $this->report->warn(
                $this->sourceType(),
                "TLD '{$tldKey}' eşlenmemiş (wisecp_tld_map) → domain #{$row->id} atlandı."
            );

            return null;
        }

        // Registrar: map'te açık procp_registrar öncelikli, yoksa WiseCP module'ü.
        $module = $mapping->procp_registrar ?: ($row->module ?: null);

        $domain = ClientDomain::create([
            'client_id' => $clientId,
            'tld_id' => (int) $mapping->procp_tld_id,
            'domain' => $domainName,
            'module' => $module ? strtolower($module) : null,
            'period' => $this->mapPeriod($row->period_time ?? 1),
            'status' => $this->mapStatus((string) ($row->status ?? '')),
            'create_date' => $this->normalizeDate($row->cdate ?? null),
            'expire_date' => $this->normalizeDate($row->duedate ?? null),
            'next_due_date' => $this->normalizeDate($row->renewaldate ?? ($row->duedate ?? null)),
            'auto_renew' => (int) ($row->auto_pay ?? 0) === 1,
        ]);

        return $domain->id;
    }

    /** WiseCP domain status → procp enum (pending|active|expired|suspended|transferred). */
    protected function mapStatus(string $status): string
    {
        return match (strtolower(trim($status))) {
            'active' => 'active',
            'expired' => 'expired',
            'cancelled', 'suspended', 'fraud' => 'suspended',
            'transferred' => 'transferred',
            // 'waiting','completed','pending' vb. → güvenli varsayılan.
            default => 'pending',
        };
    }

    /** WiseCP period_time (yıl) → procp period. Geçersiz/0 → 1. */
    protected function mapPeriod(mixed $period): int
    {
        $p = (int) $period;

        return $p >= 1 ? $p : 1;
    }

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

        return $d;
    }
}
