<?php

namespace App\Livewire\Tickets;

use App\Models\{Tickets, Departments, User, Responses};
use App\Enums\{Priorities, Status};

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\{Str, Carbon, HtmlString};
use Illuminate\Database\Eloquent\Builder;

use Livewire\Component;
use Filament\Notifications\Notification;

use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;
use Filament\Actions\{Action, BulkAction};
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Checkbox;
use Illuminate\Database\Eloquent\Collection;

class View extends Component implements HasTable, HasSchemas, HasActions
{
    use InteractsWithActions;
    use InteractsWithSchemas;
    use InteractsWithTable;

    public $selectedUser;
    public $selectedStatus;
    public $selectedPriority;
    public $showBulkActionsModal = false;

    public $bulkResponseContent;
    public $bulkResponseIsNote = false;
    public $showBulkResponseModal = false;

    public function makeFilamentTranslatableContentDriver(): ?\Filament\Support\Contracts\TranslatableContentDriver
    {
        return null;
    }

    public function table(Table $table): Table
    {
        $isAdmin = auth()->user()->hasanyrole('superadmin','admin','employee');

        $locale = str_replace('_', '-', app()->getLocale());
        $closeLabelExpression = sprintf(
            "window.pluralize('%s', getSelectedRecordsCount(), { count: new Intl.NumberFormat('%s').format(getSelectedRecordsCount()) })",
            addslashes(__('Close :count ticket|Close :count tickets')),
            $locale,
        );

        $query = $isAdmin
            ? Tickets::query()
                ->leftJoin('users', 'tickets.user_id', '=', 'users.id')
                ->leftJoin('departments', 'tickets.department_id', '=', 'departments.id')
                ->select('tickets.*')
                ->selectRaw('tickets.id as ticket_id, users.name as client_name, users.company as company_name, departments.id as department_id, departments.department_name as department_name')
            : Tickets::query()
                ->leftJoin('departments', 'tickets.department_id', '=', 'departments.id')
                ->select('tickets.*')
                ->selectRaw('tickets.id as ticket_id, departments.id as department_id, departments.department_name as department_name')
                ->where('tickets.user_id', '=', Auth::user()->id);

        $columns = [
            TextColumn::make('subject')
                ->label(strtoupper(__('Subject')))
                ->searchable()
                ->formatStateUsing(fn ($state) => Str::limit($state, 40))
                ->extraAttributes($isAdmin ? ['class' => 'min-w-90'] : ['class' => 'min-w-130']),
        ];

        if ($isAdmin) {
            $columns[] = TextColumn::make('client_name')
                ->label(strtoupper(__('Client')))
                ->searchable(query: function (Builder $query, string $search): Builder {
                    return $query->where(function ($query) use ($search) {
                        $query->where('users.name', 'like', "%{$search}%")
                              ->orWhere('users.company', 'like', "%{$search}%");
                    });
                })
                ->default(fn ($record) => $record->client_name ?? $record->public_name)
                ->extraAttributes(['class' => 'w-46']);
        }

        $columns[] = TextColumn::make('department_name')
            ->label(strtoupper(__('Department')))
            ->searchable(query: function (Builder $query, string $search): Builder {
                return $query->where('departments.department_name', 'like', "%{$search}%");
            })
            ->sortable()
            ->extraAttributes(['class' => 'w-40']);

        $columns[] = TextColumn::make('priority')
            ->label(strtoupper(__('Priority')))
            ->sortable()
            ->formatStateUsing(function ($state, $record) {
                if (empty($record->priority)) {
                    return new HtmlString(
                        '<div class="flex justify-center">'
                        . '<div class="text-xs font-medium text-gray-500 px-2.5 py-0.5 rounded-sm w-32 text-center">'
                        . e(__('None'))
                        . '</div></div>'
                    );
                }

                $colorClasses = $record->priority->colour() . ' ' . $record->priority->textcolour();
                return new HtmlString(
                    '<div class="flex justify-center">'
                    . '<div class="' . e($colorClasses) . ' text-xs font-medium px-2.5 py-0.5 rounded-sm w-32 text-center">'
                    . e($record->priority->label())
                    . '</div></div>'
                );
            })
            ->html()
            ->extraAttributes(['class' => 'w-30 text-center overflow-visible']);

        $columns[] = TextColumn::make('status')
            ->label(strtoupper(__('Status')))
            ->sortable()
            ->formatStateUsing(function ($state, $record) {
                if (empty($record->status)) {
                    return new HtmlString('');
                }

                $colorClasses = $record->status->colour() . ' ' . $record->status->textcolour();
                return new HtmlString(
                    '<div class="flex justify-center">'
                    . '<div class="' . e($colorClasses) . ' text-xs font-medium px-2.5 py-0.5 rounded-sm w-32 text-center">'
                    . e($record->status->label())
                    . '</div></div>'
                );
            })
            ->html()
            ->extraAttributes(['class' => 'w-30 text-center overflow-visible']);

        $bulkActions = [
            BulkAction::make('close')
                ->label('Close 0 tickets')
                ->icon('heroicon-o-x-circle')
                ->color('danger')
                ->button()
                ->extraAttributes([
                    'x-text' => $closeLabelExpression,
                ])
                ->requiresConfirmation()
                ->action(function (Collection $records) {
                    foreach ($records as $ticket) {
                        $this->close($ticket->ticket_id);
                    }
                    Notification::make()
                        ->title('Tickets Closed')
                        ->body("{$records->count()} ticket(s) have been successfully closed.")
                        ->success()
                        ->send();
                })
        ];

        if ($isAdmin) {
            $bulkActions[] = BulkAction::make('bulk_response')
                ->label('Bulk Response')
                ->icon('heroicon-o-chat-bubble-left-right')
                ->color('primary')
                ->button()
                ->deselectRecordsAfterCompletion(false)
                ->extraAttributes(['class' => '!bg-indigo-700 hover:!bg-indigo-500 !text-white'])
                ->action(function () {
                    $this->showBulkResponseModal = true;
                });

            $bulkActions[] = BulkAction::make('bulk_actions')
                ->label('Bulk Actions')
                ->icon('heroicon-o-cog-6-tooth')
                ->color('primary')
                ->button()
                ->deselectRecordsAfterCompletion(false)
                ->extraAttributes(['class' => '!bg-indigo-700 hover:!bg-indigo-500 !text-white'])
                ->action(function () {
                    $this->showBulkActionsModal = true;
                });
        }

        return $table
            ->query($query)
            ->columns($columns)
            ->defaultSort('ticket_id', 'desc')
            ->heading('Tickets')
            ->actions([
                Action::make('view')
                    ->label('View')
                    ->button()
                    ->size('sm')
                    ->color('primary')
                    ->url(fn (Tickets $record): string => route('show_ticket', ['ticketId' => $record->ticket_id]))
                    ->extraAttributes(['class' => '!bg-indigo-700 hover:!bg-indigo-500 !text-white'])
            ])
            ->toolbarActions($bulkActions)
            ->emptyStateHeading(__("Currently you don't have any tickets."))
            ->poll('5s')
            ->striped()
            ->paginated([10]);
    }

    public function openBulkActionsModal()
    {
        $selected = $this->getSelectedTableRecords();
        if ($selected->count() === 0) {
            Notification::make()
                ->title('No Tickets Selected')
                ->body('Please select at least one ticket to perform bulk actions.')
                ->warning()
                ->send();
            return;
        }

        $this->showBulkActionsModal = true;
    }

    public function closeBulkActionsModal()
    {
        $this->showBulkActionsModal = false;
        $this->selectedUser = null;
        $this->selectedStatus = null;
        $this->selectedPriority = null;
    }

    public function openBulkResponseModal()
    {
        $selected = $this->getSelectedTableRecords();
        if ($selected->count() === 0) {
            Notification::make()
                ->title('No Tickets Selected')
                ->body('Please select at least one ticket to send a response.')
                ->warning()
                ->send();
            return;
        }

        $this->showBulkResponseModal = true;
    }

    public function closeBulkResponseModal()
    {
        $this->showBulkResponseModal = false;
        $this->bulkResponseContent = null;
        $this->bulkResponseIsNote = false;
    }

    public function respondSelected()
    {
        if(Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
        {
            if (!$this->bulkResponseContent || trim($this->bulkResponseContent) === '') {
                Notification::make()
                    ->title('Response Required')
                    ->body('Please enter a response message.')
                    ->warning()
                    ->send();
                return;
            }

            $tickets = $this->getSelectedTableRecords();
            $count = $tickets->count();

            foreach ($tickets as $ticket) {
                Responses::create([
                    'user_id' => Auth::user()->id,
                    'content' => $this->bulkResponseContent,
                    'ticket_number' => $ticket->ticket_id,
                    'is_note' => $this->bulkResponseIsNote ? '1' : '0',
                    'employee_response' => '1',
                    'ip_address' => app('request')->ip(),
                    'created_at' => Carbon::now(),
                    'updated_at' => null,
                ]);
            }

            $responseType = $this->bulkResponseIsNote ? 'note' : 'response';

            Notification::make()
                ->title('Response Sent')
                ->body("{$count} ticket(s) have received your {$responseType}.")
                ->success()
                ->send();

            $this->deselectAllTableRecords();
            $this->closeBulkResponseModal();

            // Dispatch event to update sidebar counts
            $this->dispatch('ticket-updated')->to('sidebar-navigation');
            $this->dispatch('ticket-updated')->to('sidebar-assigned-tickets');
        }else{
            return false;
        }
    }

    public function assignSelected()
    {
        if(Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
        {
            // Check if at least one action is selected
            if (!$this->selectedUser && !$this->selectedStatus && !$this->selectedPriority) {
                Notification::make()
                    ->title('No Changes Selected')
                    ->body('Please select at least one action to perform on the tickets.')
                    ->warning()
                    ->send();
                return;
            }

            $tickets = $this->getSelectedTableRecords();
            $count = $tickets->count();

            foreach ($tickets as $ticket) {
                // Assign to employee if selected
                if ($this->selectedUser) {
                    $this->assign($ticket->ticket_id, $this->selectedUser);
                }

                // Update status if selected
                if ($this->selectedStatus) {
                    $updateData = ['status' => $this->selectedStatus];
                    if ($this->selectedStatus === 'closed') {
                        $updateData['date_closed'] = Carbon::now();
                    }
                    Tickets::where('tickets.id', '=', $ticket->ticket_id)->update($updateData);
                }

                // Update priority if selected
                if ($this->selectedPriority) {
                    Tickets::where('tickets.id', '=', $ticket->ticket_id)->update(['priority' => $this->selectedPriority]);
                }
            }

            // Build notification message
            $actions = [];
            if ($this->selectedUser) $actions[] = 'assigned';
            if ($this->selectedStatus) $actions[] = 'status updated';
            if ($this->selectedPriority) $actions[] = 'priority updated';

            $actionsText = implode(', ', $actions);

            Notification::make()
                ->title('Tickets Updated')
                ->body("{$count} ticket(s) have been successfully updated ({$actionsText}).")
                ->success()
                ->send();

            $this->deselectAllTableRecords();
            $this->closeBulkActionsModal();
        }else{
            return false;
        }
    }

    public function assign($ticket_id, $assigned_user)
    {
        Tickets::where('tickets.id', '=', $ticket_id)
            ->update([
                'assigned' => $assigned_user,
        ]);

        if($assigned_user != '0')
        {
            $employee = User::where('id', '=', $assigned_user)->first();
            $content = "This ticket has been assigned to " . $employee->name . ". Our employee will read the ticket and get back to you as soon as possible.";

            Responses::create([
                'user_id' => '0',
                'content' => $content,
                'ticket_number' => $ticket_id,
                'is_note' => '2',
                'employee_response' => '1',
                'ip_address' => '',
                'created_at' => Carbon::now(),
                'updated_at' => null,
            ]);
        }

        // Dispatch event to update sidebar counts
        $this->dispatch('ticket-updated')->to('sidebar-navigation');
        $this->dispatch('ticket-updated')->to('sidebar-assigned-tickets');
    }

    public function close($ticket_id)
    {
        Tickets::where('tickets.id', '=', $ticket_id)
            ->update([
                'status' => 'closed',
                'date_closed' => Carbon::now(),
        ]);

        if(Auth::guest())
        {
            Responses::create([
                'user_id' => '0',
                'content' => "This ticket has been closed by a guest.",
                'ticket_number' => $ticket_id,
                'is_note' => '2',
                'employee_response' => '0',
                'ip_address' => app('request')->ip(),
                'created_at' => Carbon::now(),
                'updated_at' => null,
            ]);
        } elseif(Auth::user()->id){
            if(Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
            {
                $content = "This ticket has been closed by " . Auth::user()->name . ". If you need any more assistance, simply submit a response and we'll get back to you shortly.";
                Responses::create([
                    'user_id' => '0',
                    'content' => $content,
                    'ticket_number' => $ticket_id,
                    'is_note' => '2',
                    'employee_response' => '1',
                    'ip_address' => app('request')->ip(),
                    'created_at' => Carbon::now(),
                    'updated_at' => null,
                ]);
            } else {
                $content = "This ticket has been closed. If you need any more assistance, simply submit a response and we'll get back to you shortly.";
                Responses::create([
                    'user_id' => '0',
                    'content' => $content,
                    'ticket_number' => $ticket_id,
                    'is_note' => '2',
                    'employee_response' => '0',
                    'ip_address' => app('request')->ip(),
                    'created_at' => Carbon::now(),
                    'updated_at' => null,
                ]);
            }
        }

        // Dispatch event to update sidebar counts
        $this->dispatch('ticket-updated')->to('sidebar-navigation');
        $this->dispatch('ticket-updated')->to('sidebar-assigned-tickets');
    }

    public function render()
    {
        $employees = User::role(['superadmin','admin','employee'])->get();

        return view('livewire.tickets.view',[
            'employees' => $employees,
        ]);
    }
}
