<?php

namespace App\Console\Commands;

use App\Models\User;
use App\Services\Care\DemoTenantSeeder;
use Illuminate\Console\Command;
use Illuminate\Support\Str;

/**
 * Seed plan-aware Care demo data for a platform identity (local User mirror).
 *
 * Documented invocation (when the local mirror already exists):
 *   php artisan demo:seed demo-free@ladill.com --plan=free
 *   php artisan demo:seed demo-pro@ladill.com --plan=pro --reset
 *
 * Care cannot query platform identity. To create a missing local mirror, pass
 * enough identity fields, e.g.:
 *   php artisan demo:seed --public-id=... --email=demo-free@ladill.com --name="Ladill Demo (Free)" --plan=free
 */
class DemoSeedCommand extends Command
{
    protected $signature = 'demo:seed
                            {identity? : Email or public_id of the local User mirror}
                            {--plan=free : free|pro|enterprise}
                            {--reset : Delete this tenant\'s Care demo data before re-seeding}
                            {--public-id= : Platform public_id (OIDC sub) when creating/resolving the mirror}
                            {--email= : Email when creating/resolving the mirror}
                            {--name= : Display name when creating the local mirror}';

    protected $description = 'Seed idempotent Care demo data for a suite demo account';

    public function handle(DemoTenantSeeder $seeder): int
    {
        $plan = strtolower((string) $this->option('plan'));
        if (! in_array($plan, ['free', 'pro', 'enterprise'], true)) {
            $this->error('Invalid --plan. Use free, pro, or enterprise.');

            return self::FAILURE;
        }

        try {
            $user = $this->resolveUser();
        } catch (\InvalidArgumentException $e) {
            $this->error($e->getMessage());

            return self::FAILURE;
        }

        $reset = (bool) $this->option('reset');
        $this->info(sprintf(
            'Seeding Care demo for %s (%s) plan=%s%s',
            $user->email ?: '(no email)',
            $user->public_id,
            $plan,
            $reset ? ' [reset]' : '',
        ));

        $result = $seeder->seed($user, $plan, $reset);

        $this->table(
            ['Field', 'Value'],
            [
                ['owner_ref', $user->public_id],
                ['organization', $result['organization']->name],
                ['plan', $result['plan']],
                ['plan_expires_at', data_get($result['organization']->settings, 'plan_expires_at')],
                ['billed_branches', (string) data_get($result['organization']->settings, 'billed_branches')],
                ['branches', (string) $result['branches']],
                ['patients', (string) $result['patients']],
                ['appointments', (string) $result['appointments']],
            ],
        );

        $this->info('Done.');

        return self::SUCCESS;
    }

    private function resolveUser(): User
    {
        $identity = trim((string) ($this->argument('identity') ?? ''));
        $publicId = trim((string) ($this->option('public-id') ?? ''));
        $email = trim((string) ($this->option('email') ?? ''));
        $name = trim((string) ($this->option('name') ?? ''));

        if ($identity !== '') {
            if (filter_var($identity, FILTER_VALIDATE_EMAIL)) {
                $email = $email !== '' ? $email : $identity;
            } else {
                $publicId = $publicId !== '' ? $publicId : $identity;
            }
        }

        $user = null;
        if ($publicId !== '') {
            $user = User::query()->where('public_id', $publicId)->first();
        }
        if (! $user && $email !== '') {
            $user = User::query()->where('email', $email)->first();
        }

        if ($user) {
            $updates = [];
            if ($email !== '' && $user->email !== $email) {
                $updates['email'] = $email;
            }
            if ($name !== '' && $user->name !== $name) {
                $updates['name'] = $name;
            }
            if ($updates !== []) {
                $user->forceFill($updates)->save();
            }

            return $user->fresh();
        }

        if ($publicId === '' || $email === '') {
            throw new \InvalidArgumentException(
                'Local User mirror not found. Pass an existing email/public_id, or create one with --public-id and --email (optional --name).'
            );
        }

        $user = new User([
            'public_id' => $publicId,
            'email' => $email,
            'name' => $name !== '' ? $name : Str::before($email, '@'),
        ]);
        $user->email_verified_at = now();
        $user->save();

        return $user;
    }
}
