<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Contact;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function index(Request $request)
    {
        $lateThreshold = now()->subHours(24);
        $baseQuery = Contact::query();

        $contacts = Contact::query()
            ->when($request->filled('status'), function (Builder $query) use ($request, $lateThreshold): Builder {
                $status = (string) $request->string('status');

                if ($status === 'late') {
                    return $query
                        ->whereIn('status', ['new', 'read'])
                        ->where('created_at', '<=', $lateThreshold);
                }

                return $query->where('status', $status);
            })
            ->when($request->filled('search'), function (Builder $query) use ($request): Builder {
                $search = '%' . $request->string('search') . '%';

                return $query->where(function (Builder $builder) use ($search): void {
                    $builder
                        ->where('name', 'like', $search)
                        ->orWhere('email', 'like', $search)
                        ->orWhere('message', 'like', $search);
                });
            })
            ->latest()
            ->paginate(20)
            ->withQueryString();

        $statusSummary = [
            'new' => (clone $baseQuery)->where('status', 'new')->count(),
            'read' => (clone $baseQuery)->where('status', 'read')->count(),
            'late' => (clone $baseQuery)
                ->whereIn('status', ['new', 'read'])
                ->where('created_at', '<=', $lateThreshold)
                ->count(),
            'replied' => (clone $baseQuery)->where('status', 'replied')->count(),
            'archived' => (clone $baseQuery)->where('status', 'archived')->count(),
        ];

        return view('admin.contacts.index', compact('contacts', 'statusSummary'));
    }

    public function show(Contact $contact)
    {
        if ($contact->status === 'new') {
            $contact->forceFill([
                'status' => 'read',
                'read_at' => now(),
                'notified_at' => $contact->notified_at ?: now(),
            ])->save();
        }

        return view('admin.contacts.show', compact('contact'));
    }

    public function updateNotes(Request $request, Contact $contact)
    {
        $data = $request->validate([
            'admin_notes' => 'nullable|string',
        ]);

        $contact->update($data);

        return redirect()->route('admin.contacts.show', $contact)->with('success', 'Notes updated successfully.');
    }

    public function markRead(Contact $contact)
    {
        $contact->update([
            'status' => 'read',
            'read_at' => now(),
            'notified_at' => $contact->notified_at ?: now(),
        ]);

        return back()->with('success', 'Message marked as read.');
    }

    public function markUnread(Contact $contact)
    {
        $contact->update([
            'status' => 'new',
            'read_at' => null,
            'replied_at' => null,
        ]);

        return back()->with('success', 'Message moved back to unread.');
    }

    public function markReplied(Contact $contact)
    {
        $contact->update([
            'status' => 'replied',
            'read_at' => $contact->read_at ?: now(),
            'replied_at' => now(),
            'notified_at' => $contact->notified_at ?: now(),
        ]);

        return back()->with('success', 'Message marked as replied.');
    }

    public function archive(Contact $contact)
    {
        $contact->update([
            'status' => 'archived',
            'read_at' => $contact->read_at ?: now(),
            'notified_at' => $contact->notified_at ?: now(),
        ]);

        return back()->with('success', 'Message archived.');
    }

    public function bulkUpdateStatus(Request $request)
    {
        $data = $request->validate([
            'ids' => 'required',
            'status' => 'required|in:new,read,replied,archived',
        ]);

        $ids = $this->normalizeIds($data['ids']);
        $attributes = ['status' => $data['status']];

        if (in_array($data['status'], ['read', 'replied', 'archived'], true)) {
            $attributes['read_at'] = now();
            $attributes['notified_at'] = now();
        }

        if ($data['status'] === 'replied') {
            $attributes['replied_at'] = now();
        }

        if ($data['status'] === 'new') {
            $attributes['read_at'] = null;
            $attributes['replied_at'] = null;
        }

        Contact::query()->whereIn('id', $ids)->update($attributes);

        return redirect()->route('admin.contacts.index')->with('success', 'Selected messages updated successfully.');
    }

    public function destroy(Contact $contact)
    {
        $contact->delete();

        return redirect()->route('admin.contacts.index')->with('success', 'Message deleted successfully.');
    }

    public function bulkDestroy(Request $request)
    {
        $ids = $this->normalizeIds($request->input('ids', []));
        Contact::whereIn('id', $ids)->delete();

        return redirect()->route('admin.contacts.index')->with('success', 'Selected messages deleted successfully.');
    }

    protected function normalizeIds(array|string $ids): array
    {
        if (is_string($ids)) {
            $ids = array_filter(explode(',', $ids));
        }

        return array_values(array_filter(array_map('intval', (array) $ids)));
    }
}
