<?php

namespace App\Http\Controllers;

use App\Models\FieldJob;
use App\Services\ReferenceDataCache;
use Illuminate\Http\Request;
use Inertia\Inertia;

class PhoneViewController extends Controller
{
    public function __construct(protected ReferenceDataCache $referenceCache) {}

    public function index(Request $request): \Inertia\Response
    {
        $userId = $request->user()->id;
        $search = $request->input('search');
        $clientFilter = $request->input('client');

        $eagerLoad = [
            'contract' => function ($q) {
                $q->with([
                    'type:id,name',
                    'account',
                    'clientCase.person.address.type',
                    'clientCase.person.phones',
                    'clientCase.client:id,uuid,person_id',
                    'clientCase.client.person:id,full_name',
                ]);
            },
        ];

        $baseQuery = FieldJob::query()
            ->where('assigned_user_id', $userId)
            ->whereNull('completed_at')
            ->whereNull('cancelled_at')
            ->with($eagerLoad);

        if ($clientFilter) {
            $baseQuery->whereHas('contract.clientCase.client', function ($q) use ($clientFilter) {
                $q->where('uuid', $clientFilter);
            });
        }

        if ($search) {
            $baseQuery->where(function ($q) use ($search) {
                $q->whereHas('contract', function ($cq) use ($search) {
                    $cq->where('reference', 'ilike', '%'.$search.'%')
                        ->orWhereHas('clientCase.person', function ($pq) use ($search) {
                            $pq->where('full_name', 'ilike', '%'.$search.'%');
                        })
                        ->orWhereHas('clientCase.client.person', function ($pq) use ($search) {
                            $pq->where('full_name', 'ilike', '%'.$search.'%');
                        });
                });
            });
        }

        $pendingQuery = (clone $baseQuery)
            ->where(fn ($q) => $q->where('added_activity', false)->orWhereNull('added_activity'))
            ->orderByDesc('assigned_at');

        $processedQuery = (clone $baseQuery)
            ->where('added_activity', true)
            ->orderByDesc('assigned_at');

        $clients = \App\Models\Client::query()
            ->whereHas('clientCases.contracts.fieldJobs', function ($q) use ($userId) {
                $q->where('assigned_user_id', $userId)
                    ->whereNull('completed_at')
                    ->whereNull('cancelled_at');
            })
            ->with(['person:id,full_name'])
            ->get(['uuid', 'person_id'])
            ->map(fn ($c) => [
                'uuid' => (string) $c->uuid,
                'name' => (string) optional($c->person)->full_name,
            ])
            ->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE)
            ->values();

        return Inertia::render('Phone/Index', [
            'pendingJobs' => Inertia::scroll(fn () => $pendingQuery->paginate(15, pageName: 'pending')),
            'processedJobs' => Inertia::scroll(fn () => $processedQuery->paginate(15, pageName: 'processed')),
            'clients' => $clients,
            'view_mode' => 'assigned',
            'filters' => [
                'search' => $search,
                'client' => $clientFilter,
            ],
        ]);
    }

    public function completedToday(Request $request): \Inertia\Response
    {
        $userId = $request->user()->id;
        $search = $request->input('search');
        $clientFilter = $request->input('client');

        $start = now()->startOfDay();
        $end = now()->endOfDay();

        $query = FieldJob::query()
            ->where('assigned_user_id', $userId)
            ->whereNull('cancelled_at')
            ->whereBetween('completed_at', [$start, $end])
            ->with([
                'contract' => function ($q) {
                    $q->with([
                        'type:id,name',
                        'account',
                        'clientCase.person.address.type',
                        'clientCase.person.phones',
                        'clientCase.client:id,uuid,person_id',
                        'clientCase.client.person:id,full_name',
                    ]);
                },
            ])
            ->orderByDesc('completed_at');

        // Apply client filter
        if ($clientFilter) {
            $query->whereHas('contract.clientCase.client', function ($q) use ($clientFilter) {
                $q->where('uuid', $clientFilter);
            });
        }

        // Apply search filter
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->whereHas('contract', function ($cq) use ($search) {
                    $cq->where('reference', 'ilike', '%'.$search.'%')
                        ->orWhereHas('clientCase.person', function ($pq) use ($search) {
                            $pq->where('full_name', 'ilike', '%'.$search.'%');
                        })
                        ->orWhereHas('clientCase.client.person', function ($pq) use ($search) {
                            $pq->where('full_name', 'ilike', '%'.$search.'%');
                        });
                });
            });
        }

        $clients = \App\Models\Client::query()
            ->whereHas('clientCases.contracts.fieldJobs', function ($q) use ($userId, $start, $end) {
                $q->where('assigned_user_id', $userId)
                    ->whereNull('cancelled_at')
                    ->whereBetween('completed_at', [$start, $end]);
            })
            ->with(['person:id,full_name'])
            ->get(['uuid', 'person_id'])
            ->map(fn ($c) => [
                'uuid' => (string) $c->uuid,
                'name' => (string) optional($c->person)->full_name,
            ])
            ->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE)
            ->values();

        return Inertia::render('Phone/Index', [
            'completedJobs' => Inertia::scroll(fn () => $query->paginate(15, pageName: 'completed')),
            'clients' => $clients,
            'view_mode' => 'completed-today',
            'filters' => [
                'search' => $search,
                'client' => $clientFilter,
            ],
        ]);
    }

    public function showCase(\App\Models\ClientCase $clientCase, Request $request)
    {
        $userId = $request->user()->id;
        $completedMode = $request->boolean('completed');

        // Eager load case with person details
        $case = $clientCase->load('person.address.type', 'person.phones', 'person.emails', 'person.bankAccounts');

        // Query contracts based on field jobs
        $contractsQuery = FieldJob::query()
            ->where('assigned_user_id', $userId)
            ->whereHas('contract', fn ($q) => $q->where('client_case_id', $case->id))
            ->when($completedMode,
                fn ($q) => $q->whereNull('cancelled_at')->whereBetween('completed_at', [now()->startOfDay(), now()->endOfDay()]),
                fn ($q) => $q->whereNull('completed_at')->whereNull('cancelled_at')
            );

        // Get contracts with relationships
        $contracts = \App\Models\Contract::query()
            ->where('client_case_id', $case->id)
            ->whereIn('id', $contractsQuery->pluck('contract_id')->unique())
            ->with(['type:id,name', 'account', 'latestObject'])
            ->orderByDesc('created_at')
            ->get();

        // Build merged documents
        $documents = $case->documents()
            ->orderByDesc('created_at')
            ->get()
            ->map(fn ($d) => array_merge($d->toArray(), [
                'documentable_type' => \App\Models\ClientCase::class,
                'client_case_uuid' => $case->uuid,
            ]))
            ->concat(
                \App\Models\Document::query()
                    ->where('documentable_type', \App\Models\Contract::class)
                    ->whereIn('documentable_id', $contracts->pluck('id'))
                    ->with('documentable:id,uuid,reference')
                    ->orderByDesc('created_at')
                    ->get()
                    ->map(fn ($d) => array_merge($d->toArray(), [
                        'contract_reference' => $d->documentable?->reference,
                        'contract_uuid' => $d->documentable?->uuid,
                    ]))
            )
            ->sortByDesc('created_at')
            ->values();

        // Get segment IDs for filtering actions
        $segmentIds = \App\Models\FieldJobSetting::query()
            ->whereIn('id', $contractsQuery->pluck('field_job_setting_id')->filter()->unique())
            ->pluck('segment_id')
            ->filter()
            ->unique();

        return Inertia::render('Phone/Case/Index', [
            'client' => $case->client->load('person.address.type', 'person.phones', 'person.emails', 'person.bankAccounts'),
            'client_case' => $case,
            'contracts' => $contracts,
            'documents' => $documents,
            'types' => [
                'address_types' => \App\Models\Person\AddressType::all(),
                'phone_types' => \App\Models\Person\PhoneType::all(),
            ],
            'account_types' => \App\Models\AccountType::all(),
            'actions' => \App\Models\Action::query()
                ->when($segmentIds->isNotEmpty(), fn ($q) => $q->whereIn('segment_id', $segmentIds))
                ->with([
                    'decisions:id,name,color_tag,auto_mail,email_template_id',
                    'decisions.emailTemplate:id,name,entity_types,allow_attachments',
                ])
                ->get(['id', 'name', 'color_tag', 'segment_id']),
            'activities' => $case->activities()
                ->with(['action', 'decision', 'contract:id,uuid,reference', 'user:id,name'])
                ->orderByDesc('created_at')
                ->limit(20)
                ->get()
                ->map(fn ($a) => $a->setAttribute('user_name', $a->user?->name)),
            'completed_mode' => $completedMode,
        ]);
    }
}
