<?php

namespace App\Console\Commands;

use App\Models\Feedback;
use App\Models\Item;
use App\Models\LoginHistory;
use App\Models\Offer;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class StatusOverview extends Command
{
    /**
     * Read-only snapshot of the environment — users, items, transactions and
     * marketplace activity. Handy for checking on beta after time away, and
     * usable on production with filters to keep the output manageable.
     */
    protected $signature = 'status:overview
        {--email= : Show a detailed profile for a single user by email}
        {--users : Only show the users section}
        {--items : Only show the items section}
        {--transactions : Only show the transactions section}
        {--unverified : List unverified users (id, name, email, joined)}
        {--limit=10 : Rows to show in the recent-users / recent-logins tables}';

    protected $description = 'Show a read-only status overview of users, items and marketplace activity';

    public function handle(): int
    {
        // Single-user lookup short-circuits everything else.
        if ($email = $this->option('email')) {
            return $this->showUser($email);
        }

        $this->environmentLine();

        // If any section flag is passed, show only those; otherwise show all.
        $only = collect(['users', 'items', 'transactions'])
            ->filter(fn ($s) => $this->option($s));
        $showAll = $only->isEmpty();

        if ($this->option('unverified')) {
            return $this->listUnverified();
        }

        if ($showAll || $only->contains('users')) {
            $this->usersSection();
        }
        if ($showAll || $only->contains('items')) {
            $this->itemsSection();
        }
        if ($showAll || $only->contains('transactions')) {
            $this->transactionsSection();
        }
        if ($showAll) {
            $this->activitySection();
        }

        return self::SUCCESS;
    }

    private function environmentLine(): void
    {
        $pending = $this->pendingMigrationCount();
        $this->newLine();
        $this->line(sprintf(
            '<fg=cyan;options=bold>%s</> — <fg=gray>%s</>',
            strtoupper((string) config('app.env')),
            config('app.url')
        ));
        $this->line(sprintf(
            'DB: %s   Pending migrations: %s',
            config('database.connections.'.config('database.default').'.database'),
            $pending === 0 ? '<fg=green>none</>' : "<fg=yellow>{$pending}</>"
        ));
    }

    private function usersSection(): void
    {
        $limit = (int) $this->option('limit');

        $total = User::count();
        $verified = User::whereNotNull('email_verified_at')->count();
        $admins = User::where('is_admin', true)->count();
        $vacation = User::where('is_on_vacation', true)->count();

        $this->section('Users');
        $this->line(sprintf(
            'Total: <options=bold>%d</>   Verified: %d   Unverified: <fg=%s>%d</>   Admins: %d   On vacation: %d',
            $total,
            $verified,
            $total - $verified > 0 ? 'yellow' : 'green',
            $total - $verified,
            $admins,
            $vacation
        ));

        $recent = User::latest()->limit($limit)->get();
        if ($recent->isNotEmpty()) {
            $this->newLine();
            $this->line("<fg=gray>Most recent {$recent->count()} users:</>");
            $this->table(
                ['ID', 'Name', 'Email', 'Verified', 'Admin', 'Joined'],
                $recent->map(fn (User $u) => [
                    $u->id,
                    $u->name,
                    $u->email,
                    $u->email_verified_at ? 'yes' : 'NO',
                    $u->is_admin ? 'yes' : '',
                    $u->created_at?->format('Y-m-d H:i'),
                ])->all()
            );
        }

        // Recent logins are the best "who's been poking at beta" signal.
        if (Schema::hasTable('login_histories')) {
            $logins = LoginHistory::with('user')
                ->latest('logged_in_at')
                ->limit($limit)
                ->get();
            if ($logins->isNotEmpty()) {
                $this->line("<fg=gray>Recent logins:</>");
                $this->table(
                    ['User', 'IP', 'When'],
                    $logins->map(fn (LoginHistory $l) => [
                        $l->user?->email ?? "#{$l->user_id}",
                        $l->ip_address,
                        optional($l->logged_in_at)->diffForHumans() ?? '',
                    ])->all()
                );
            }
        }
    }

    private function itemsSection(): void
    {
        $this->section('Items');

        $byStatus = Item::select('status', DB::raw('count(*) as c'))
            ->groupBy('status')
            ->pluck('c', 'status');

        if ($byStatus->isEmpty()) {
            $this->line('<fg=gray>No items.</>');
            return;
        }

        $this->line('Total: <options=bold>'.$byStatus->sum().'</>');
        $this->table(
            ['Status', 'Count'],
            $byStatus->map(fn ($c, $s) => [$s, $c])->values()->all()
        );
    }

    private function transactionsSection(): void
    {
        $this->section('Transactions');

        $byStatus = Transaction::select('status', DB::raw('count(*) as c'))
            ->groupBy('status')
            ->pluck('c', 'status');

        if ($byStatus->isEmpty()) {
            $this->line('<fg=gray>No transactions.</>');
            return;
        }

        $this->line('Total: <options=bold>'.$byStatus->sum().'</>');
        $this->table(
            ['Status', 'Count'],
            $byStatus->map(fn ($c, $s) => [$s, $c])->values()->all()
        );

        // What the next auto-close run will sweep up.
        $due = Transaction::where('status', 'pending')
            ->whereNotNull('auto_close_at')
            ->where('auto_close_at', '<=', now())
            ->count();
        if ($due > 0) {
            $this->line("<fg=yellow>{$due} pending transaction(s) past auto_close_at (next run will complete these).</>");
        }
    }

    private function activitySection(): void
    {
        $this->section('Marketplace activity');

        $openOffers = Offer::where('status', 'pending')->count();
        $queueDepth = Schema::hasTable('buy_queue')
            ? DB::table('buy_queue')->count()
            : 0;
        $feedback = Schema::hasTable('feedback') ? Feedback::count() : 0;

        $this->line(sprintf(
            'Open offers: %d   Buy-queue entries: %d   Feedback/ratings: %d',
            $openOffers,
            $queueDepth,
            $feedback
        ));
    }

    private function listUnverified(): int
    {
        $limit = (int) $this->option('limit');
        $users = User::whereNull('email_verified_at')
            ->latest()
            ->limit($limit)
            ->get();

        $this->section('Unverified users');
        if ($users->isEmpty()) {
            $this->info('None — every user is verified.');
            return self::SUCCESS;
        }

        $this->table(
            ['ID', 'Name', 'Email', 'Joined'],
            $users->map(fn (User $u) => [
                $u->id,
                $u->name,
                $u->email,
                $u->created_at?->format('Y-m-d H:i'),
            ])->all()
        );
        $this->line("<fg=gray>Showing up to {$limit}; pass --limit to see more.</>");

        return self::SUCCESS;
    }

    private function showUser(string $email): int
    {
        $user = User::where('email', $email)->first();
        if (! $user) {
            $this->error("No user with email {$email}");
            return self::FAILURE;
        }

        $this->section("User #{$user->id}");
        $this->table(['Field', 'Value'], [
            ['Name', $user->name],
            ['Email', $user->email],
            ['Verified', $user->email_verified_at ? $user->email_verified_at->format('Y-m-d H:i') : 'NO'],
            ['Admin', $user->is_admin ? 'yes' : 'no'],
            ['On vacation', $user->is_on_vacation ? 'yes' : 'no'],
            ['Joined', $user->created_at?->format('Y-m-d H:i')],
            ['Items', Item::where('user_id', $user->id)->count()],
            ['Sales (seller)', Transaction::where('seller_id', $user->id)->count()],
            ['Purchases (buyer)', Transaction::where('buyer_id', $user->id)->count()],
        ]);

        return self::SUCCESS;
    }

    private function section(string $title): void
    {
        $this->newLine();
        $this->line("<fg=cyan;options=bold>── {$title} ──</>");
    }

    private function pendingMigrationCount(): int
    {
        try {
            $ran = DB::table('migrations')->pluck('migration')->all();
            $files = glob(database_path('migrations/*.php')) ?: [];
            $all = array_map(fn ($f) => basename($f, '.php'), $files);
            return count(array_diff($all, $ran));
        } catch (\Throwable) {
            return 0;
        }
    }
}
