<?php

namespace App\Console\Commands;

use App\Actions\Jetstream\RestoreProfile;
use App\Models\Admin;
use App\Models\Bank;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class RestoreDeletedProfile extends Command
{
    protected $signature = 'profiles:restore
                            {username? : The username of the profile to restore}
                            {--list : List all deleted profiles within grace period}
                            {--type= : Filter by profile type (user, organization, bank, admin)}';

    protected $description = 'Restore a deleted profile within the grace period or list all restorable profiles';

    public function handle()
    {
        // If --list option is provided, show all deleted profiles
        if ($this->option('list')) {
            return $this->listDeletedProfiles();
        }

        // Get username argument
        $username = $this->argument('username');

        // If no username provided, ask for it
        if (!$username) {
            $username = $this->ask('Enter the username of the profile to restore');
        }

        if (!$username) {
            $this->error('Username is required.');
            return 1;
        }

        // Search for the deleted profile
        $profile = $this->findDeletedProfile($username);

        if (!$profile) {
            $this->error("No deleted profile found with username: {$username}");
            $this->info('Use --list option to see all restorable profiles.');
            return 1;
        }

        // Display profile information
        $profileType = class_basename(get_class($profile));
        $deletedAt = $profile->deleted_at;
        $gracePeriodDays = timebank_config('delete_profile.grace_period_days', 30);
        $expiresAt = $deletedAt->copy()->addDays($gracePeriodDays);

        // Calculate remaining time more accurately
        if (now()->greaterThanOrEqualTo($expiresAt)) {
            $timeRemaining = 'EXPIRED';
        } else {
            $daysRemaining = now()->diffInDays($expiresAt, false);
            if ($daysRemaining > 0) {
                $timeRemaining = $daysRemaining . ' day' . ($daysRemaining > 1 ? 's' : '');
            } else {
                $hoursRemaining = now()->diffInHours($expiresAt, false);
                $timeRemaining = $hoursRemaining . ' hour' . ($hoursRemaining > 1 ? 's' : '');
            }
        }

        $this->info("Profile found:");
        $this->table(
            ['Field', 'Value'],
            [
                ['Type', $profileType],
                ['Username', $profile->name],
                ['Full Name', $profile->full_name ?? 'N/A'],
                ['Email', $profile->email],
                ['Deleted At', $deletedAt->format('Y-m-d H:i:s')],
                ['Grace Period Expires', $expiresAt->format('Y-m-d H:i:s')],
                ['Days Remaining', $timeRemaining],
            ]
        );

        // Confirm restoration
        if (!$this->confirm('Do you want to restore this profile?')) {
            $this->info('Restoration cancelled.');
            return 0;
        }

        // Restore the profile
        $restoreAction = new RestoreProfile();
        $result = $restoreAction->restore($profile);

        if ($result['status'] === 'success') {
            $this->info("✓ Profile '{$profile->name}' has been successfully restored!");
            Log::info("Profile restored via artisan command", [
                'profile_type' => get_class($profile),
                'profile_id' => $profile->id,
                'profile_name' => $profile->name,
                'restored_by' => 'CLI',
            ]);
            return 0;
        } else {
            $this->error("✗ Failed to restore profile: {$result['message']}");
            return 1;
        }
    }

    /**
     * List all deleted profiles within grace period
     */
    protected function listDeletedProfiles()
    {
        $gracePeriodDays = timebank_config('delete_profile.grace_period_days', 30);
        $gracePeriodExpiry = now()->subDays($gracePeriodDays);

        $profileTypes = [
            'User' => User::class,
            'Organization' => Organization::class,
            'Bank' => Bank::class,
            'Admin' => Admin::class,
        ];

        // Filter by type if provided
        $typeFilter = $this->option('type');
        if ($typeFilter) {
            $typeFilter = ucfirst(strtolower($typeFilter));
            if (!isset($profileTypes[$typeFilter])) {
                $this->error("Invalid profile type. Valid types: user, organization, bank, admin");
                return 1;
            }
            $profileTypes = [$typeFilter => $profileTypes[$typeFilter]];
        }

        $allDeletedProfiles = [];

        foreach ($profileTypes as $typeName => $modelClass) {
            // Find profiles that are deleted, within grace period, and not anonymized
            $profiles = $modelClass::whereNotNull('deleted_at')
                ->where('deleted_at', '>', $gracePeriodExpiry)
                ->where('email', 'not like', 'removed-%@remove.ed')
                ->orderBy('deleted_at', 'desc')
                ->get();

            foreach ($profiles as $profile) {
                $expiresAt = $profile->deleted_at->copy()->addDays($gracePeriodDays);

                // Calculate remaining time more accurately
                if (now()->greaterThanOrEqualTo($expiresAt)) {
                    $timeRemaining = 'EXPIRED';
                } else {
                    $daysRemaining = now()->diffInDays($expiresAt, false);
                    if ($daysRemaining > 0) {
                        $timeRemaining = $daysRemaining . 'd';
                    } else {
                        $hoursRemaining = now()->diffInHours($expiresAt, false);
                        $timeRemaining = $hoursRemaining . 'h';
                    }
                }

                $allDeletedProfiles[] = [
                    'Type' => $typeName,
                    'Username' => $profile->name,
                    'Full Name' => $profile->full_name ?? 'N/A',
                    'Email' => $profile->email,
                    'Deleted At' => $profile->deleted_at->format('Y-m-d H:i'),
                    'Expires At' => $expiresAt->format('Y-m-d H:i'),
                    'Time Left' => $timeRemaining,
                    'Comment' => $profile->comment ?? '',
                ];
            }
        }

        if (empty($allDeletedProfiles)) {
            $this->info('No deleted profiles found within the grace period.');
            return 0;
        }

        $this->info("Deleted profiles within {$gracePeriodDays}-day grace period:");
        $this->table(
            ['Type', 'Username', 'Full Name', 'Email', 'Deleted At', 'Expires At', 'Time Left', 'Comment'],
            $allDeletedProfiles
        );

        $this->info("\nTo restore a profile, run: php artisan profiles:restore {username}");

        return 0;
    }

    /**
     * Find a deleted profile by username across all profile types
     */
    protected function findDeletedProfile($username)
    {
        $gracePeriodDays = timebank_config('delete_profile.grace_period_days', 30);
        $gracePeriodExpiry = now()->subDays($gracePeriodDays);

        $profileTypes = [
            User::class,
            Organization::class,
            Bank::class,
            Admin::class,
        ];

        foreach ($profileTypes as $modelClass) {
            $profile = $modelClass::whereNotNull('deleted_at')
                ->where('deleted_at', '>', $gracePeriodExpiry)
                ->where('email', 'not like', 'removed-%@remove.ed')
                ->where('name', $username)
                ->first();

            if ($profile) {
                return $profile;
            }
        }

        return null;
    }
}
