<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\DomainCostDestroyRequest;
use App\Http\Requests\Admin\DomainCostIndexRequest;
use App\Http\Requests\Admin\DomainCostStoreRequest;
use App\Http\Requests\Admin\DomainCostUpdateRequest;
use App\Models\DomainCost;
use App\Models\Pricing;
use App\Models\Tld;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class DomainCostController extends Controller
{
    use LogsAdminActivity;
    /**
     * Display a listing of domain costs.
     */
    public function index(DomainCostIndexRequest $request): View
    {
        // Sadece aktif TLD'ler
        $tlds = Tld::where('status', 'active')->orderBy('tld')->get(['id', 'tld']);

        return view('admin.domain-costs.index', compact('tlds'));
    }

    /**
     * Show the form for creating a new domain cost.
     */
    public function create(): View
    {
        // PRC-500 — index()/edit() ile aynı pattern; create blade tld_id
        // select'i bu listeyle doldurulur (önceden $tlds geçmiyordu →
        // select boştu, required → form submit edilemiyordu).
        $tlds = Tld::where('status', 'active')->orderBy('tld')->get(['id', 'tld']);

        return view('admin.domain-costs.create', compact('tlds'));
    }

    /**
     * Store a newly created domain cost.
     */
    public function store(DomainCostStoreRequest $request): JsonResponse
    {
        try {
            $validated = $request->validated();

            // Prices'ı dizi formatında al
            $prices = $request->input('prices', []);
            if (is_string($prices)) {
                $prices = json_decode($prices, true) ?: [];
            }

            $domainCost = DB::transaction(function () use ($validated, $prices) {
                // DomainCost kaydını oluştur
                $domainCost = DomainCost::create([
                    'tld_id' => $validated['tld_id'],
                    'registrar' => $validated['registrar'],
                    'is_active' => $validated['is_active'],
                    'metadata' => $validated['metadata'] ?? [],
                ]);

                // Pricing kayıtlarını oluştur
                foreach ($prices as $year => $amount) {
                    if ($amount > 0) {
                        Pricing::create([
                            'type' => 'domain_cost',
                            'relation_id' => $domainCost->id,
                            'segment' => 'cost',
                            'period' => $year,
                            'time' => 'year',
                            'amount' => $amount,
                            'currency_id' => $validated['currency_id'],
                            'order' => 0,
                        ]);
                    }
                }

                return $domainCost;
            });

            $this->logCreated($domainCost, "Created domain cost #{$domainCost->id} for TLD ID {$domainCost->tld_id}");

            return response()->json([
                'success' => true,
                'message' => __('admin/domain-costs.messages_created'),
            ]);
        } catch (\Exception $e) {
            \Log::error('Domain cost creation failed', ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return response()->json([
                'success' => false,
                'message' => __('admin/common.general_error'),
            ], 500);
        }
    }

    /**
     * Display the specified domain cost.
     */
    public function show(DomainCost $domainCost): View
    {
        return view('admin.domain-costs.show', compact('domainCost'));
    }

    /**
     * Show the form for editing the specified domain cost.
     */
    public function edit(DomainCost $domainCost): View
    {
        $tlds = Tld::orderBy('tld')->get(['id', 'tld']);

        // Aktif olmayan registrar'lar da dahil olmak üzere tüm registrar'ları al
        $registrars = \App\Models\Registrar::orderBy('name')->get(['id', 'name']);

        // Pricing verilerini hazırla
        $prices = [];
        $currencyId = null;
        foreach ($domainCost->pricings as $pricing) {
            $prices[$pricing->period] = $pricing->amount;
            if (! $currencyId) {
                $currencyId = $pricing->currency_id;
            }
        }

        $domainCostPrepared = [
            'id' => $domainCost->id,
            'tld_id' => $domainCost->tld_id,
            'registrar' => $domainCost->registrar,
            'currency_id' => $currencyId,
            'prices' => $prices,
            'is_active' => $domainCost->is_active,
        ];

        return view('admin.domain-costs.edit', compact('domainCost', 'tlds', 'registrars', 'domainCostPrepared'));
    }

    /**
     * Update the specified domain cost.
     */
    public function update(DomainCostUpdateRequest $request, DomainCost $domainCost): JsonResponse
    {
        try {
            $validated = $request->validated();

            // Prices'ı dizi formatında al
            $prices = $request->input('prices', []);
            if (is_string($prices)) {
                $prices = json_decode($prices, true) ?: [];
            }

            DB::transaction(function () use ($domainCost, $validated, $prices) {
                // DomainCost'u güncelle
                $domainCost->update([
                    'tld_id' => $validated['tld_id'],
                    'registrar' => $validated['registrar'],
                    'is_active' => $validated['is_active'],
                ]);

                // Eski pricing kayıtlarını sil
                Pricing::where('type', 'domain_cost')
                    ->where('relation_id', $domainCost->id)
                    ->delete();

                // Yeni pricing kayıtlarını oluştur
                foreach ($prices as $year => $amount) {
                    if ($amount > 0) {
                        Pricing::create([
                            'type' => 'domain_cost',
                            'relation_id' => $domainCost->id,
                            'segment' => 'cost',
                            'period' => $year,
                            'time' => 'year',
                            'amount' => $amount,
                            'currency_id' => $validated['currency_id'],
                            'order' => 0,
                        ]);
                    }
                }
            });

            $this->logUpdated($domainCost, "Updated domain cost #{$domainCost->id} for TLD ID {$domainCost->tld_id}");

            return response()->json([
                'success' => true,
                'message' => __('admin/domain-costs.messages_updated'),
                'data' => $domainCost,
            ]);
        } catch (\Exception $e) {
            \Log::error('Domain cost update failed', ['domain_cost_id' => $domainCost->id, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return response()->json([
                'success' => false,
                'message' => __('admin/common.general_error'),
            ], 500);
        }
    }

    /**
     * Remove the specified domain cost.
     */
    public function destroy(DomainCostDestroyRequest $request, DomainCost $domainCost): JsonResponse
    {
        try {
            $this->logDeleted($domainCost, "Deleted domain cost #{$domainCost->id} for TLD ID {$domainCost->tld_id}");

            DB::transaction(function () use ($domainCost) {
                // İlişkili pricing kayıtlarını sil
                Pricing::where('type', 'domain_cost')
                    ->where('relation_id', $domainCost->id)
                    ->delete();

                // DomainCost kaydını sil
                $domainCost->delete();
            });

            return response()->json([
                'success' => true,
                'message' => __('admin/domain-costs.messages_deleted'),
            ]);
        } catch (\Exception $e) {
            \Log::error('Domain cost deletion failed', ['domain_cost_id' => $domainCost->id, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return response()->json([
                'success' => false,
                'message' => __('admin/common.general_error'),
            ], 500);
        }
    }

    /**
     * Get domain costs for DataTable.
     */
    public function records(Request $request): JsonResponse
    {
        // DomainCost'ları grupla ve pricing verilerini al
        $query = DomainCost::with(['tld'])
            ->leftJoin('tlds', 'tlds.id', '=', 'domain_costs.tld_id')
            ->select('domain_costs.*');

        // Apply filters
        if ($request->filled('tld_id')) {
            $query->where('tld_id', $request->integer('tld_id'));
        }

        if ($request->filled('registrar')) {
            $query->where('registrar', $request->registrar);
        }

        if ($request->filled('is_active')) {
            $query->where('is_active', $request->boolean('is_active'));
        }

        // Apply search (DataTables 'search' parametresi dizi olabilir: ['value' => '...'])
        $rawSearch = $request->input('search');
        $searchTerm = null;
        if (is_array($rawSearch)) {
            $searchTerm = $rawSearch['value'] ?? null;
        } elseif (! is_null($rawSearch)) {
            $searchTerm = (string) $rawSearch;
        }

        if ($searchTerm !== null && $searchTerm !== '') {
            $query->where(function ($q) use ($searchTerm) {
                $q->where('tlds.tld', 'like', "%{$searchTerm}%")
                    ->orWhere('domain_costs.registrar', 'like', "%{$searchTerm}%");
            });
        }

        // Apply sorting
        $sortColumn = $request->input('sort_column', 'tld');
        $sortDirection = $request->input('sort_direction', 'asc');
        // Sıralama kolon eşlemesi
        $sortableColumns = [
            'tld' => 'tlds.tld',
            'registrar' => 'domain_costs.registrar',
            'created_at' => 'domain_costs.created_at',
        ];
        $orderByColumn = $sortableColumns[$sortColumn] ?? 'tlds.tld';
        $query->orderBy($orderByColumn, $sortDirection);

        // Get paginated results
        $perPage = $request->input('per_page', 15);
        $domainCosts = $query->paginate($perPage);

        $data = $domainCosts->getCollection()->map(function ($domainCost) {
            // Pricing kayıtlarından yılları ve currency'yi al
            $pricingRecords = Pricing::where('type', 'domain_cost')
                ->where('relation_id', $domainCost->id)
                ->where('amount', '>', 0)
                ->orderBy('period', 'asc')
                ->get(['period', 'amount', 'currency_id']);

            $years = $pricingRecords->pluck('period')->toArray();
            $prices = $pricingRecords->pluck('amount', 'period')->toArray();

            // Currency bilgisini al (ilk pricing kaydından)
            $firstPricing = $pricingRecords->first();
            $currencyCode = $firstPricing ? \App\Models\Currency::find($firstPricing->currency_id)?->code : null;

            return [
                'id' => $domainCost->id,
                'tld' => $domainCost->tld?->tld,
                'tld_id' => $domainCost->tld_id,
                'registrar' => $domainCost->registrar,
                'currency_id' => $currencyCode,
                'prices' => $prices,
                'years' => $years,
                'is_active' => $domainCost->is_active,
                'is_currently_active' => $domainCost->isCurrentlyActive(),
                'created_at' => $domainCost->created_at->format('Y-m-d H:i:s'),
                'updated_at' => $domainCost->updated_at->format('Y-m-d H:i:s'),
            ];
        });

        return response()->json([
            'draw' => $request->input('draw', 1),
            'recordsTotal' => $domainCosts->total(),
            'recordsFiltered' => $domainCosts->total(),
            'data' => $data,
        ]);
    }

    /**
     * Get domain costs by TLD for API usage.
     */
    public function getByTld(Request $request, $tldId): JsonResponse
    {
        $domainCosts = DomainCost::with(['pricings'])
            ->where('tld_id', $tldId)
            ->where('is_active', true)
            ->get();

        $result = [];
        foreach ($domainCosts as $domainCost) {
            $prices = [];
            $currencyCode = null;

            foreach ($domainCost->pricings as $pricing) {
                $prices[$pricing->period] = $pricing->amount;
                if (! $currencyCode) {
                    $currencyCode = \App\Models\Currency::find($pricing->currency_id)?->code;
                }
            }

            $result[] = [
                'id' => $domainCost->id,
                'registrar' => $domainCost->registrar,
                'currency' => $currencyCode,
                'prices' => $prices,
            ];
        }

        return response()->json($result);
    }
}
