<?php

namespace App\Filament\Pages;

use BackedEnum;
use UnitEnum;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use App\Models\ActivationKey;
use App\Models\Plan;
use Filament\Actions\BulkAction;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Tables\Columns\BooleanColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Filters\SelectFilter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Response;

class GenerateActivationKeys extends Page implements HasForms, HasTable
{
    use InteractsWithForms, InteractsWithTable;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-key';

    protected string $view = 'filament.pages.generate-activation-keys';

    protected static string|UnitEnum|null $navigationGroup = 'Admin';

    protected static ?string $title = 'Activation Keys';

    public $plan_id;

    public $quantity = 1;

    public function mount(): void
    {
        $this->form->fill();
    }

    protected function getFormSchema(): array
    {
        return [
            Select::make('plan_id')
                ->label('Select Plan')
                ->options(Plan::all()->pluck('name', 'id'))
                ->required(),

            TextInput::make('quantity')
                ->numeric()
                ->minValue(1)
                ->maxValue(100)
                ->default(1)
                ->required(),
        ];
    }

    public function generate(): void
    {
        $data = $this->form->getState();
        $plan = Plan::query()->findOrFail($data['plan_id']);

        for ($i = 0; $i < $data['quantity']; $i++) {
            ActivationKey::query()->create([
                'price_id' => $plan->pricing_id,
                'activation_key' => strtoupper('Z'.Str::random(16)),
                'is_activated' => false,
            ]);
        }

        Notification::make()
            ->title("{$data['quantity']} activation key(s) generated.")
            ->success()
            ->send();
        $this->form->fill(); // Reset form
    }

    // === Table Setup ===
    protected function getTableQuery(): Builder
    {
        return ActivationKey::query()->latest();
    }

    protected function getTableColumns(): array
    {
        return [
            TextColumn::make('activation_key')
                ->label('Key')
                ->copyable(),

            BooleanColumn::make('is_activated'),

            TextColumn::make('user.email')
                ->label('Activated By'),

            TextColumn::make('billing_interval')
                ->label('Interval')
                ->getStateUsing(function ($record): string {
                    $isMonthly = Plan::query()->where('pricing_id', $record->price_id)->value('monthly_billing');

                    return $isMonthly ? 'Monthly' : 'Yearly';
                }),

            TextColumn::make('created_at')
                ->dateTime(),
        ];
    }

    protected function getTableFilters(): array
    {
        return [
            SelectFilter::make('is_activated')
                ->options([
                    true => 'Activated',
                    false => 'Not Activated',
                ]),
            SelectFilter::make('price_id')
                ->label('Plan')
                ->options(
                    Plan::query()->pluck('name', 'pricing_id')
                ),
        ];
    }

    protected function getTableBulkActions(): array
    {
        return [
            BulkAction::make('Download Keys')
                ->action(fn (Collection $records): BinaryFileResponse => $this->downloadKeys($records))
                ->deselectRecordsAfterCompletion()
                ->requiresConfirmation(),
        ];
    }

    public function downloadKeys(Collection $records): BinaryFileResponse
    {
        $text = $records->pluck('activation_key')->implode("\n");

        $filename = 'activation_keys_'.now()->timestamp.'.txt';
        // Store the file in the 'public' directory or a subdirectory within 'public'
        $path = public_path("activation/{$filename}");

        // Make sure the 'activation' folder exists, create it if it doesn't
        if (! file_exists(public_path('activation'))) {
            mkdir(public_path('activation'), 0777, true);
        }

        // Write the contents to the file
        file_put_contents($path, $text);

        // Return the response that allows users to download the file directly
        return response()->download($path)->deleteFileAfterSend(true);
    }
}
