<?php

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Mtc\Crm\Contracts\Customer;

class SavedSearchController extends Controller
{
    /**
     * List authenticated user's saved searches.
     */
    public function index(): JsonResponse
    {
        $customer = $this->getAuthenticatedCustomer();

        if (!$customer) {
            return response()->json(['message' => 'Customer not found'], 404);
        }

        $savedSearches = $customer->savedSearches()
            ->with('filters')
            ->latest()
            ->get()
            ->map(fn ($search) => [
                'id' => $search->id,
                'name' => $search->name,
                'sort_by' => $search->sort_by,
                'notifications_enabled' => $search->notifications_enabled,
                'filters' => $search->filters->map(fn ($f) => [
                    'type' => $f->type,
                    'value' => $f->value,
                ]),
                'created_at' => $search->created_at->format('d/m/Y H:i'),
            ]);

        return response()->json(['data' => $savedSearches]);
    }

    /**
     * Save current search filters.
     */
    public function store(Request $request): JsonResponse
    {
        $customer = $this->getAuthenticatedCustomer();

        if (!$customer) {
            return response()->json(['message' => 'Customer not found'], 404);
        }

        $request->validate([
            'filters' => ['required', 'array', 'min:1'],
            'filters.*.type' => ['required', 'string'],
            'filters.*.value' => ['required', 'string'],
            'name' => ['nullable', 'string', 'max:255'],
            'sort_by' => ['nullable', 'string'],
            'notifications_enabled' => ['sometimes', 'boolean'],
        ]);

        $name = $request->input('name') ?: $this->generateNameFromFilters($request->input('filters'));

        $savedSearch = $customer->savedSearches()->create([
            'name' => $name,
            'sort_by' => $request->input('sort_by'),
            'notifications_enabled' => $request->boolean('notifications_enabled', false),
        ]);

        foreach ($request->input('filters') as $filter) {
            $savedSearch->filters()->create([
                'type' => $filter['type'],
                'value' => $filter['value'],
            ]);
        }

        return response()->json([
            'id' => $savedSearch->id,
            'name' => $savedSearch->name,
            'message' => 'Search saved successfully',
        ], 201);
    }

    /**
     * Delete a saved search.
     */
    public function destroy(int $id): JsonResponse
    {
        $customer = $this->getAuthenticatedCustomer();

        if (!$customer) {
            return response()->json(['message' => 'Customer not found'], 404);
        }

        $savedSearch = $customer->savedSearches()->find($id);

        if (!$savedSearch) {
            return response()->json(['message' => 'Saved search not found'], 404);
        }

        $savedSearch->delete();

        return response()->json(['message' => 'Saved search deleted successfully']);
    }

    /**
     * Get the customer associated with the authenticated user.
     */
    private function getAuthenticatedCustomer(): ?Customer
    {
        $user = Auth::user();

        if (!$user) {
            return null;
        }

        $customerModel = config('crm.customer_model');

        return $customerModel::where('email', $user->email)->first();
    }

    /**
     * Generate a descriptive name from filters.
     *
     * @param array $filters
     * @return string
     */
    private function generateNameFromFilters(array $filters): string
    {
        $parts = [];
        $filtersByType = [];

        foreach ($filters as $filter) {
            $type = $filter['type'];
            $value = $filter['value'];
            $filtersByType[$type][] = $value;
        }

        if (isset($filtersByType['make'])) {
            $parts[] = ucfirst(implode('/', $filtersByType['make']));
        }

        if (isset($filtersByType['model'])) {
            $parts[] = ucfirst(implode('/', $filtersByType['model']));
        }

        if (isset($filtersByType['price_max'])) {
            $parts[] = 'under £' . number_format((float) $filtersByType['price_max'][0], 0);
        } elseif (isset($filtersByType['price_min'])) {
            $parts[] = 'from £' . number_format((float) $filtersByType['price_min'][0], 0);
        }

        if (isset($filtersByType['fuel_type'])) {
            $parts[] = ucfirst(implode('/', $filtersByType['fuel_type']));
        }

        if (isset($filtersByType['body_type'])) {
            $parts[] = ucfirst(implode('/', $filtersByType['body_type']));
        }

        if (isset($filtersByType['colour'])) {
            $parts[] = ucfirst(implode('/', $filtersByType['colour']));
        }

        if (empty($parts)) {
            return 'Saved Search ' . now()->format('d/m/Y H:i');
        }

        return implode(' ', $parts);
    }
}
