<?php

namespace Spatie\Mailcoach\Livewire\Audience;

use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\BulkAction;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\HtmlString;
use Livewire\Features\SupportRedirects\Redirector;
use Spatie\Mailcoach\Domain\Audience\Models\EmailList;
use Spatie\Mailcoach\Domain\Audience\Models\TagSegment;
use Spatie\Mailcoach\Livewire\TableComponent;
use Spatie\Mailcoach\MainNavigation;

class SegmentsComponent extends TableComponent
{
    use InteractsWithActions;

    public EmailList $emailList;

    public function mount(EmailList $emailList)
    {
        $this->authorize('view', $emailList);

        $this->emailList = $emailList;

        app(MainNavigation::class)->activeSection()?->add($this->emailList->name, route('mailcoach.emailLists.segments', $this->emailList));
    }

    public function table(Table $table): Table
    {
        return parent::table($table)
            ->query($this->emailList->segments()->getQuery())
            ->recordUrl(function (TagSegment $record) {
                return route('mailcoach.emailLists.segments.edit', [$this->emailList, $record]);
            })
            ->defaultSort('name')
            ->emptyStateDescription(function (Table $table) {
                if ($table->getQuery()->count()) {
                    return '';
                }

                return __mc('A segment is a group of tags that can be targeted by an email campaign. You can learn more about segmentation & tags in our docs');
            })
            ->emptyStateIcon('heroicon-s-user-group')
            ->emptyStateActions([
                Action::make(__mc('Learn more'))
                    ->url('https://mailcoach.app/resources/learn-mailcoach/features/segmentation-tags')
                    ->link()
                    ->extraAttributes(['class' => 'link'])
                    ->openUrlInNewTab(),
            ])
            ->columns($this->columns())
            ->recordActions($this->recordActions())
            ->toolbarActions($this->toolbarActions());
    }

    protected function columns(): array
    {
        return [
            TextColumn::make('name')
                ->label(__mc('Name'))
                ->sortable()
                ->searchable()
                ->extraAttributes(['class' => 'link']),
            TextColumn::make('population')
                ->name(__mc('Population'))
                ->numeric()
                ->extraAttributes([
                    'class' => 'tabular-nums',
                ])
                ->view('mailcoach::app.emailLists.segments.columns.population')
                ->alignRight(),
            TextColumn::make('created_at')
                ->size('base')
                ->extraAttributes([
                    'class' => 'tabular-nums',
                ])
                ->date(config('mailcoach.date_format'))
                ->alignRight()
                ->sortable(),
        ];
    }

    protected function recordActions(): array
    {
        return [
            ActionGroup::make([
                Action::make('Duplicate')
                    ->visible(fn (TagSegment $record) => Auth::user()->can('create', $record::class))
                    ->action(fn (TagSegment $record) => $this->duplicateSegment($record))
                    ->icon('heroicon-s-document-duplicate')
                    ->label(__mc('Duplicate')),
                Action::make('Delete')
                    ->visible(fn (TagSegment $record) => Auth::user()->can('delete', $record))
                    ->action(function (TagSegment $record) {
                        $record->delete();
                        notify(__mc('Segment :segment was deleted.', ['segment' => $record->name]));
                    })
                    ->requiresConfirmation()
                    ->label(__mc('Delete'))
                    ->modalHeading(fn (TagSegment $record) => __mc('Delete :resource', ['resource' => __mc('segment')]))
                    ->modalDescription(fn (TagSegment $record) => new HtmlString(__mc('Are you sure you want to delete :resource<br/><strong>:name</strong>?', [
                        'resource' => __mc('segment'),
                        'name' => $record->name,
                    ])))
                    ->icon('heroicon-s-trash')
                    ->color('danger'),
            ]),
        ];
    }

    protected function toolbarActions(): array
    {
        return [
            BulkAction::make('Delete')
                ->visible(fn () => Auth::user()->can('update', $this->emailList))
                ->label(__mc('Delete'))
                ->icon('heroicon-s-trash')
                ->requiresConfirmation()
                ->color('danger')
                ->deselectRecordsAfterCompletion()
                ->action(function ($records) {
                    $this->authorize('update', $this->emailList);

                    $records->each->delete();

                    notify(__mc('Successfully deleted :count segments', ['count' => $records->count()]));
                }),
        ];
    }

    public function duplicateSegment(TagSegment $segment): RedirectResponse|Redirector
    {
        $this->authorize('create', self::getTagSegmentClass());

        /** @var TagSegment $duplicateSegment */
        $duplicateSegment = self::getTagSegmentClass()::create([
            'name' => "{$segment->name} - ".__mc('copy'),
            'email_list_id' => $segment->email_list_id,
            'stored_conditions' => $segment->stored_conditions,
        ]);

        notify(__mc('Segment :segment was created.', ['segment' => $segment->name]));

        return redirect()->route('mailcoach.emailLists.segments.edit', [
            $duplicateSegment->emailList,
            $duplicateSegment,
        ]);
    }

    public function getTitle(): string
    {
        return __mc('Segments');
    }

    public function getLayout(): string
    {
        return 'mailcoach::app.emailLists.layouts.emailList';
    }

    public function getLayoutData(): array
    {
        $data = [
            'emailList' => $this->emailList,
        ];

        if (Auth::guard(config('mailcoach.guard'))->user()->can('create', self::getTagSegmentClass())) {
            $data['create'] = 'segment';
            $data['createData'] = [
                'emailList' => $this->emailList,
            ];
        }

        return $data;
    }
}
