<?php

namespace App\Modules\Addon\MigrateWhmcs\Importers;

use App\Models\ClientProduct;
use Illuminate\Support\Facades\DB;

/**
 * PRC-1113 — WHMCS `tblhosting` → procp `ClientProduct` (hizmet/servis) importer.
 *
 * Tek satır eşleme: client_id ledger'dan çözülür (yoksa skip), product_id
 * whmcs_product_map'ten çözülür (eşlenmemişse skip). Kimlik/lifecycle alanları
 * WHMCS'ten map'lenir; parola encrypted-cast ile atanır (asla düz/loglanmaz).
 *
 * DB kolonları AbstractWhmcsImporter sözleşmesi + gerçek şema doğrulanarak
 * yazıldı: kaynak `tblhosting` (domainstatus/regdate/nextduedate/amount),
 * hedef `client_products` ($fillable + status enum ['pending','active',
 * 'suspended','terminated']).
 */
class ServiceImporter extends AbstractWhmcsImporter
{
    public function sourceType(): string
    {
        return 'service';
    }

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

    protected function importRow(object $row): ?int
    {
        // FK: WHMCS userid → procp client id (parent henüz import edilmediyse skip).
        $clientId = $this->ledger->map('client', $row->userid);
        if ($clientId === null) {
            $this->report->warn(
                $this->sourceType(),
                "Servis #{$row->id}: client (userid={$row->userid}) henüz import edilmemiş, atlandı."
            );

            return null;
        }

        // Ürün eşlemesi: WHMCS packageid → procp product (+ modül). Eşlenmemişse
        // tahmin etme, atla.
        $map = DB::table('whmcs_product_map')
            ->where('whmcs_product_id', $row->packageid)
            ->first();

        if ($map === null || $map->procp_product_id === null) {
            $this->report->warn(
                $this->sourceType(),
                "Servis #{$row->id}: WHMCS product (packageid={$row->packageid}) eşlenmemiş, atlandı."
            );

            return null;
        }

        $product = ClientProduct::create([
            'client_id' => (int) $clientId,
            'product_id' => (int) $map->procp_product_id,
            'module' => $map->procp_module ?? null,
            'domain' => $this->trimOrNull($row->domain),
            'username' => $this->trimOrNull($row->username),
            // Encrypted cast (setPasswordAttribute mutator) — değeri ata, cast
            // şifreler; asla loglama.
            'password' => ($row->password === null || $row->password === '') ? null : $row->password,
            'billingcycle' => $this->mapBillingCycle($row->billingcycle),
            'recurring_amount' => $row->amount,
            'status' => $this->mapStatus($row->domainstatus),
            'create_date' => $this->normalizeDate($row->regdate),
            'next_due_date' => $this->normalizeDate($row->nextduedate ?? null),
            'dedicated_ip' => $this->trimOrNull($row->dedicatedip ?? null),
            'notes' => $this->trimOrNull($row->notes ?? null),
        ]);

        return $product->id;
    }

    /**
     * WHMCS billingcycle metnini procp billingcycle anahtarına indirger.
     * Eşleşme yoksa null (procp kolonu nullable) — tahmin üretmez.
     */
    private function mapBillingCycle(?string $cycle): ?string
    {
        $key = strtolower(trim((string) $cycle));

        return match ($key) {
            'monthly' => 'monthly',
            'quarterly' => 'quarterly',
            'semi-annually', 'semiannually', 'semi_annually' => 'semi_annually',
            'annually', 'yearly' => 'annually',
            'biennially' => 'biennially',
            'triennially' => 'triennially',
            default => null,
        };
    }

    /**
     * WHMCS domainstatus → procp status enum ['pending','active','suspended',
     * 'terminated']. Cancelled/Fraud gibi ara durumlar en yakın terminal
     * duruma (terminated) düşürülür; boş/bilinmeyen → pending.
     */
    private function mapStatus(?string $status): string
    {
        return match (strtolower(trim((string) $status))) {
            'active' => 'active',
            'suspended' => 'suspended',
            'terminated', 'cancelled', 'canceled', 'fraud', 'closed' => 'terminated',
            default => 'pending',
        };
    }

    /**
     * WHMCS boş tarih ('0000-00-00' / '' / null) → null; aksi hâlde değer.
     */
    private function normalizeDate(?string $date): ?string
    {
        if ($date === null) {
            return null;
        }
        $date = trim($date);
        if ($date === '' || str_starts_with($date, '0000-00-00')) {
            return null;
        }

        return $date;
    }

    private function trimOrNull(?string $value): ?string
    {
        if ($value === null) {
            return null;
        }
        $value = trim($value);

        return $value === '' ? null : $value;
    }
}
