<?php

namespace Spatie\Mailcoach\Livewire\Content;

use Filament\Actions\BulkAction;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Support\Facades\DB;
use Spatie\Mailcoach\Domain\Automation\Models\AutomationMail;
use Spatie\Mailcoach\Domain\Campaign\Models\Campaign;
use Spatie\Mailcoach\Domain\Content\Models\Click;

class LinkClicksComponent extends ContentItemTable
{
    use InteractsWithActions;

    public string $linkUuids;

    public function table(Table $table): Table
    {
        return parent::table($table)
            ->defaultKeySort(false)
            ->columns($this->tableColumns())
            ->toolbarActions($this->toolbarActions())
            ->query($this->query())
            ->recordUrl(function ($record) {
                return route('mailcoach.emailLists.subscriber.details',
                    [$record->subscriber_email_list_uuid, $record->subscriber_uuid]);
            })
            ->defaultSort('first_clicked_at', 'desc')
            ->paginated();
    }

    protected function query(): EloquentBuilder
    {
        $prefix = DB::getTablePrefix();

        $clickTable = static::getClickTableName();
        $subscriberTableName = static::getSubscriberTableName();
        $emailListTableName = static::getEmailListTableName();

        return static::getClickClass()::query()
            ->selectRaw("
                    {$prefix}{$subscriberTableName}.id as id,
                    {$prefix}{$subscriberTableName}.uuid as subscriber_uuid,
                    {$prefix}{$emailListTableName}.uuid as subscriber_email_list_uuid,
                    {$prefix}{$subscriberTableName}.email as subscriber_email,
                    count({$prefix}{$clickTable}.subscriber_id) as click_count,
                    min({$prefix}{$clickTable}.created_at) AS first_clicked_at
                ")
            ->join(static::getLinkTableName(), static::getLinkTableName().'.id', '=', "{$clickTable}.link_id")
            ->join($subscriberTableName, "{$subscriberTableName}.id", '=', "{$clickTable}.subscriber_id")
            ->join($emailListTableName, "{$subscriberTableName}.email_list_id", '=', "{$emailListTableName}.id")
            ->whereIn(static::getLinkTableName().'.uuid', explode(',', $this->linkUuids))
            ->groupBy("{$subscriberTableName}.id", "{$subscriberTableName}.uuid", "{$emailListTableName}.uuid",
                "{$subscriberTableName}.email");
    }

    public function getTitle(): string
    {
        $firstUuid = explode(',', $this->linkUuids)[0];

        return str_replace(['https://', 'http://', '/', '\\'], ['', '', '_', '_'],
            self::getLinkClass()::findByUuid($firstUuid)->url);
    }

    public function getOriginTitle(): string
    {
        return "{$this->model->name} / ".__mc('Clicks');
    }

    public function getOriginHref(): string
    {
        return match (true) {
            $this->model instanceof Campaign => route('mailcoach.campaigns.clicks', $this->model),
            $this->model instanceof AutomationMail => route('mailcoach.automations.mails.clicks', $this->model),
            default => '',
        };
    }

    protected function tableColumns(): array
    {
        $searchable = $this->query()->count() > $this->defaultPaginationOptions[0] || request('tableFilters');

        return [
            TextColumn::make('subscriber_email')
                ->label(__mc('Email'))
                ->sortable()
                ->extraAttributes(['class' => 'link'])
                ->searchable($searchable, query: function (Builder $query, string $search) {
                    $query->where(self::getSubscriberTableName().'.email', 'like', "%{$search}%");
                }),
            TextColumn::make('click_count')
                ->label(__mc('Clicks'))
                ->sortable()
                ->numeric()
                ->extraAttributes([
                    'class' => 'tabular-nums',
                ]),
            TextColumn::make('first_clicked_at')
                ->sortable()
                ->label(__mc('First clicked at'))
                ->dateTime(config('mailcoach.date_format')),
        ];
    }

    protected function toolbarActions(): array
    {
        $prefix = DB::getTablePrefix();
        $subscriberTableName = static::getSubscriberTableName();

        return [
            BulkAction::make('export')
                ->label(__mc('Export selected'))
                ->icon('heroicon-s-cloud-arrow-down')
                ->action(function () use ($prefix, $subscriberTableName) {
                    $header = [
                        'email',
                        'clicks',
                        'first_clicked_at',
                    ];

                    $rows = $this->getTable()->getQuery()->whereIn("{$prefix}{$subscriberTableName}.id",
                        $this->selectedTableRecords)->get();

                    return $this->export(
                        header: $header,
                        rows: $rows,
                        formatRow: function (Click $row) {
                            return [
                                'email' => $row->subscriber_email,
                                'clicks' => $row->click_count,
                                'first_clicked_at' => $row->first_clicked_at->toMailcoachFormat(),
                            ];
                        },
                        title: $this->getTitle(),
                    );
                }),
        ];
    }
}
