<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\BasketDestroyRequest;
use App\Http\Requests\Admin\BasketEditRequest;
use App\Http\Requests\Admin\BasketIndexRequest;
use App\Http\Requests\Admin\BasketRecordsRequest;
use App\Http\Requests\Admin\BasketShowRequest;
use App\Http\Requests\Admin\BasketStoreRequest;
use App\Http\Requests\Admin\BasketUpdateRequest;
use App\Models\Basket;
use App\Services\BasketService;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\Request;

class BasketController extends Controller
{
    use LogsAdminActivity;
    protected BasketService $basketService;

    public function __construct(BasketService $basketService)
    {
        $this->basketService = $basketService;
    }

    /**
     * Display a listing of the resource.
     */
    public function index(BasketIndexRequest $request)
    {
        return view('admin.baskets.index');
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $this->authorize('create', Basket::class);

        // Müşteri listesini al
        $clients = \App\Models\Client::orderBy('first_name')->get();

        return view('admin.baskets.create', compact('clients'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(BasketStoreRequest $request)
    {
        $validated = $request->validated();

        // Sepet verisi hazırla
        $basketData = [
            'items' => $validated['basket_data']['items'] ?? [],
        ];

        // Her ürün için added_at ekle
        foreach ($basketData['items'] as &$item) {
            $item['added_at'] = now()->toISOString();
        }

        $basket = Basket::create([
            'session_id' => $validated['session_id'],
            'ip_address' => $validated['ip_address'],
            'client_id' => $validated['client_id'],
            'basket_data' => $basketData,
            'last_activity_at' => $validated['last_activity_at'] ?? now(),
            'expires_at' => $validated['expires_at'] ?? now()->addDays(config('basket.expiration_days', 30)),
        ]);

        $this->logCreated($basket, "Created basket #{$basket->id}", $basket->client_id);

        return redirect()->route('admin.baskets.index')
            ->with('success', __('admin/baskets.messages_created'));
    }

    /**
     * Display the specified resource.
     */
    public function show(BasketShowRequest $request, Basket $basket)
    {
        $basket->load('client');

        return view('admin.baskets.show', compact('basket'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(BasketEditRequest $request, Basket $basket)
    {
        $basket->load('client');

        // Müşteri listesini al
        $clients = \App\Models\Client::orderBy('first_name')->get();

        return view('admin.baskets.edit', compact('basket', 'clients'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(BasketUpdateRequest $request, Basket $basket)
    {
        $validated = $request->validated();

        // Sepet verisi hazırla
        $basketData = [
            'items' => $validated['basket_data']['items'] ?? [],
        ];

        // Her ürün için added_at ekle (eğer yoksa)
        foreach ($basketData['items'] as &$item) {
            if (! isset($item['added_at'])) {
                $item['added_at'] = now()->toISOString();
            }
        }

        $basket->update([
            'session_id' => $validated['session_id'],
            'ip_address' => $validated['ip_address'],
            'client_id' => $validated['client_id'],
            'basket_data' => $basketData,
            'last_activity_at' => $validated['last_activity_at'] ?? now(),
            'expires_at' => $validated['expires_at'] ?? $basket->expires_at,
        ]);

        $this->logUpdated($basket, "Updated basket #{$basket->id}", $basket->client_id);

        return redirect()->route('admin.baskets.show', $basket)
            ->with('success', __('admin/baskets.messages_updated'));
    }

    /**
     * Remove the specified resource from storage.
     * Handles both Redis visitor baskets and MySQL baskets.
     */
    public function destroy(BasketDestroyRequest $request, string $id)
    {
        $source = $request->input('source', 'mysql');
        $visitorId = $request->input('visitor_id', $id);

        if ($source === 'redis') {
            // Delete from Redis
            $this->basketService->deleteRedisBasket($visitorId);

            return response()->json([
                'success' => true,
                'message' => __('admin/baskets.messages_deleted'),
            ]);
        }

        // Delete from MySQL
        $basket = Basket::find($id);

        if (!$basket) {
            return response()->json([
                'success' => false,
                'message' => __('admin/baskets.messages_not_found'),
            ], 404);
        }

        $this->authorize('delete', $basket);

        $this->logDeleted($basket, "Deleted basket #{$basket->id}", $basket->client_id);

        $basket->delete();

        return response()->json([
            'success' => true,
            'message' => __('admin/baskets.messages_deleted'),
        ]);
    }

    /**
     * Get baskets for DataTables (combines Redis and MySQL)
     */
    public function records(BasketRecordsRequest $request)
    {
        // Get all baskets from Redis and MySQL
        $filters = [];
        if ($request->filled('status')) {
            $filters['status'] = $request->status;
        }

        $allBaskets = $this->basketService->getAllBasketsForAdmin($filters);

        // Convert to collection for easier manipulation
        $collection = collect($allBaskets);

        // Apply search filter
        if ($request->filled('search')) {
            $rawSearch = $request->input('search');
            $search = strtolower(is_array($rawSearch) ? ($rawSearch['value'] ?? '') : (string) $rawSearch);

            if (!empty($search)) {
                $collection = $collection->filter(function ($basket) use ($search) {
                    return str_contains(strtolower($basket['visitor_id'] ?? ''), $search) ||
                           str_contains(strtolower($basket['ip_address'] ?? ''), $search) ||
                           str_contains(strtolower($basket['client_name'] ?? ''), $search) ||
                           str_contains(strtolower($basket['client_email'] ?? ''), $search) ||
                           str_contains(strtolower($basket['country'] ?? ''), $search) ||
                           str_contains(strtolower($basket['city'] ?? ''), $search);
                });
            }
        }

        // Apply status filter for Redis baskets
        if ($request->filled('status')) {
            $status = $request->status;
            $collection = $collection->filter(function ($basket) use ($status) {
                switch ($status) {
                    case 'active':
                        return !empty($basket['items']);
                    case 'empty':
                        return empty($basket['items']);
                    case 'anonymous':
                        return empty($basket['client_id']);
                    case 'client':
                        return !empty($basket['client_id']);
                    default:
                        return true;
                }
            });
        }

        // Filter by has_items
        if ($request->filled('has_items')) {
            $hasItems = $request->has_items === 'yes';
            $collection = $collection->filter(function ($basket) use ($hasItems) {
                return $hasItems ? !empty($basket['items']) : empty($basket['items']);
            });
        }

        $total = $collection->count();

        // Sorting
        $orderColumn = $request->input('order.0.column', 0);
        $orderDir = $request->input('order.0.dir', 'desc');

        $sortFields = [
            'visitor_id', 'ip_address', 'country', 'client_name',
            'item_count', 'total', 'last_seen_at', 'created_at',
        ];

        $sortField = $sortFields[$orderColumn] ?? 'created_at';
        $collection = $orderDir === 'asc'
            ? $collection->sortBy($sortField)
            : $collection->sortByDesc($sortField);

        // Pagination
        $start = $request->input('start', 0);
        $length = $request->input('length', 10);
        $baskets = $collection->slice($start, $length)->values();

        // Format data for DataTable
        $data = $baskets->map(function ($basket) {
            $lastSeen = $basket['last_seen_at'] ?? $basket['updated_at'] ?? null;
            $createdAt = $basket['created_at'] ?? null;

            return [
                'visitor_id' => $this->shortenVisitorId($basket['visitor_id'] ?? ''),
                'visitor_id_full' => $basket['visitor_id'] ?? '',
                'ip_address' => $basket['ip_address'] ?? '-',
                'location' => $this->formatLocation($basket),
                'client_name' => $basket['client_name'] ?? __('admin/baskets.anonymous'),
                'client_email' => $basket['client_email'] ?? '-',
                'client_id' => $basket['client_id'] ?? null,
                'item_count' => $basket['item_count'] ?? 0,
                'total' => number_format($basket['total'] ?? 0, 2),
                'currency' => $basket['currency'] ?? 'TRY',
                'coupon_code' => $basket['coupon_code'] ?? null,
                'status' => !empty($basket['items']) ? 'active' : 'empty',
                'source' => $basket['source'] ?? 'unknown',
                'last_seen' => $lastSeen ? \Carbon\Carbon::parse($lastSeen)->format('d.m.Y H:i') : '-',
                'created_at' => $createdAt ? \Carbon\Carbon::parse($createdAt)->format('d.m.Y H:i') : '-',
            ];
        })->toArray();

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

    /**
     * Shorten visitor ID for display
     */
    private function shortenVisitorId(string $visitorId): string
    {
        if (strlen($visitorId) > 12) {
            return substr($visitorId, 0, 8) . '...' . substr($visitorId, -4);
        }
        return $visitorId;
    }

    /**
     * Format location from basket data
     */
    private function formatLocation(array $basket): string
    {
        $parts = [];
        if (!empty($basket['city'])) {
            $parts[] = $basket['city'];
        }
        if (!empty($basket['country'])) {
            $parts[] = $basket['country'];
        }
        if (!empty($basket['country_code']) && empty($parts)) {
            $parts[] = $basket['country_code'];
        }
        return !empty($parts) ? implode(', ', $parts) : '-';
    }

    /**
     * Get basket statistics
     */
    public function statistics()
    {
        $stats = $this->basketService->getStatistics();

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

    /**
     * Cleanup expired baskets
     */
    public function cleanupExpired()
    {
        $count = $this->basketService->cleanupExpiredBaskets();

        return response()->json([
            'success' => true,
            'message' => __('admin/baskets.messages_expired_cleaned', ['count' => $count]),
            'count' => $count,
        ]);
    }

    /**
     * Cleanup old baskets
     */
    public function cleanupOld(Request $request)
    {
        $days = $request->input('days', 60);
        $count = $this->basketService->cleanupOldBaskets($days);

        return response()->json([
            'success' => true,
            'message' => __('admin/baskets.messages_old_cleaned', ['count' => $count, 'days' => $days]),
            'count' => $count,
        ]);
    }

    /**
     * Get baskets for reminder
     */
    public function reminderBaskets()
    {
        $baskets = $this->basketService->getBasketsForReminder();

        return response()->json([
            'success' => true,
            'data' => $baskets->map(function ($basket) {
                return [
                    'id' => $basket->id,
                    'client_name' => $basket->client->name,
                    'client_email' => $basket->client->email,
                    'item_count' => $basket->itemCount,
                    'total' => $basket->total,
                    'last_activity' => $basket->last_activity_at->format('d.m.Y H:i'),
                    'expires_at' => $basket->expires_at->format('d.m.Y H:i'),
                ];
            }),
        ]);
    }

    /**
     * Get basket details for modal view
     */
    public function details(Request $request, string $visitorId)
    {
        $source = $request->input('source', 'redis');

        if ($source === 'redis') {
            // Get Redis basket data
            $basketData = \App\Helpers\VisitorHelper::getVisitorBasket($visitorId);
            $visitorDetails = \Illuminate\Support\Facades\Cache::get(
                \App\Services\VisitorService::CACHE_PREFIX . $visitorId,
                []
            );

            if (empty($basketData)) {
                return response()->json([
                    'success' => false,
                    'message' => __('admin/baskets.messages_not_found'),
                ], 404);
            }

            $items = $basketData['items'] ?? [];
            $total = 0;
            foreach ($items as $item) {
                $total += ($item['price'] ?? 0) * ($item['quantity'] ?? 1);
            }

            // Get client info if linked
            $client = null;
            $clientId = $visitorDetails['userId'] ?? null;
            if ($clientId) {
                $client = \App\Models\Client::find($clientId);
            }

            return response()->json([
                'success' => true,
                'data' => [
                    'visitor_id' => $visitorId,
                    'source' => 'redis',
                    'visitor' => [
                        'ip_address' => $visitorDetails['ipAddress'] ?? null,
                        'country' => $visitorDetails['country'] ?? null,
                        'country_code' => $visitorDetails['countryCode'] ?? null,
                        'city' => $visitorDetails['city'] ?? null,
                        'state' => $visitorDetails['state'] ?? null,
                        'timezone' => $visitorDetails['timezone'] ?? null,
                        'browser_language' => $visitorDetails['browserLanguage'] ?? null,
                        'preferred_language' => $visitorDetails['preferredLanguage'] ?? null,
                        'preferred_currency' => $visitorDetails['preferredCurrency'] ?? null,
                        'created_at' => $visitorDetails['createdAt'] ?? null,
                        'last_seen_at' => $visitorDetails['lastSeenAt'] ?? null,
                    ],
                    'client' => $client ? [
                        'id' => $client->id,
                        'name' => $client->getAdminDisplayName(),
                        'email' => $client->email,
                        'company' => $client->company,
                    ] : null,
                    'items' => collect($items)->map(function ($item) {
                        return [
                            'type' => $item['type'] ?? 'product',
                            'name' => $item['name'] ?? $item['product_name'] ?? 'Unknown',
                            'description' => $item['description'] ?? null,
                            'domain_name' => $item['domain_name'] ?? null,
                            'domain_action' => $item['domain_action'] ?? null,
                            'price' => $item['price'] ?? 0,
                            'quantity' => $item['quantity'] ?? 1,
                            'period' => $item['period'] ?? null,
                            'period_text' => $item['period_text'] ?? null,
                            'currency' => $item['currency'] ?? 'TRY',
                            'added_at' => $item['addedAt'] ?? $item['added_at'] ?? null,
                            'config_options' => $item['config_options'] ?? null,
                        ];
                    })->values()->toArray(),
                    'coupon_code' => $basketData['coupon_code'] ?? null,
                    'item_count' => count($items),
                    'total' => $total,
                    'currency' => $visitorDetails['preferredCurrency'] ?? $visitorDetails['currency'] ?? 'TRY',
                    'created_at' => $basketData['created_at'] ?? null,
                    'updated_at' => $basketData['updated_at'] ?? null,
                ],
            ]);
        }

        // MySQL basket
        $basket = Basket::with('client')->find($visitorId);

        if (!$basket) {
            return response()->json([
                'success' => false,
                'message' => __('admin/baskets.messages_not_found'),
            ], 404);
        }

        $items = $basket->basket_data['items'] ?? [];

        return response()->json([
            'success' => true,
            'data' => [
                'visitor_id' => $basket->session_id,
                'source' => 'mysql',
                'visitor' => [
                    'ip_address' => $basket->ip_address,
                    'country' => null,
                    'country_code' => null,
                    'city' => null,
                    'state' => null,
                    'timezone' => null,
                    'browser_language' => null,
                    'preferred_language' => null,
                    'preferred_currency' => null,
                    'created_at' => $basket->created_at?->toISOString(),
                    'last_seen_at' => $basket->last_activity_at?->toISOString(),
                ],
                'client' => $basket->client ? [
                    'id' => $basket->client->id,
                    'name' => $basket->client->first_name . ' ' . $basket->client->last_name,
                    'email' => $basket->client->email,
                    'company' => $basket->client->company,
                ] : null,
                'items' => collect($items)->map(function ($item) {
                    return [
                        'type' => $item['type'] ?? 'product',
                        'name' => $item['name'] ?? $item['product_name'] ?? 'Unknown',
                        'description' => $item['description'] ?? null,
                        'domain_name' => $item['domain_name'] ?? null,
                        'domain_action' => $item['domain_action'] ?? null,
                        'price' => $item['price'] ?? 0,
                        'quantity' => $item['quantity'] ?? 1,
                        'period' => $item['period'] ?? null,
                        'period_text' => $item['period_text'] ?? null,
                        'currency' => $item['currency'] ?? 'TRY',
                        'added_at' => $item['added_at'] ?? null,
                        'config_options' => $item['config_options'] ?? null,
                    ];
                })->values()->toArray(),
                'coupon_code' => $basket->basket_data['coupon_code'] ?? null,
                'item_count' => count($items),
                'total' => $basket->total,
                'currency' => 'TRY',
                'created_at' => $basket->created_at?->toISOString(),
                'updated_at' => $basket->updated_at?->toISOString(),
                'expires_at' => $basket->expires_at?->toISOString(),
            ],
        ]);
    }
}
