<?php

namespace App\Console\Commands;

use App\Models\MigrationUserPlan;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

#[Signature('migrate:users:plan {--fresh}')]
#[Description('Construct migration plan for WP/XF accounts.')]
class MigrateUsersPlan extends Command
{
    public function handle()
    {
        if( $this->option('fresh') ) {
            MigrationUserPlan::truncate();
        }

        $this->info("Loading old XF accounts...");

        $xfUsers = DB::connection('old_xf')->table('user')
            ->select('user_id','username','email')
            ->get()
            ->keyBy('user_id')
        ;

        $xfUsersByEmail = $xfUsers->groupBy(fn($u) => strtolower($u->email));

        $this->info("Loading old WP accounts...");

        $wpUsers = DB::connection('old_wp')->table('users')
            ->leftJoin('usermeta', function ($join) {
               $join->on('users.ID', '=', 'usermeta.user_id')->where('usermeta.meta_key', '=', 'xf_user_id');
            })
            ->select('users.ID as wp_id', 'users.user_email as email', 'users.user_login as username', 'usermeta.meta_value as linked_xf_id')
            ->get();

        $linkedXfIds = [];

        $this->withProgressBar( $wpUsers, function ($wp) use ($xfUsers, $xfUsersByEmail, &$linkedXfIds) {
            $email = strtolower($wp->email);
            $linkedId = $wp->linked_xf_id ? (int) $wp->linked_xf_id : null;

            if( $linkedId && $xfUsers->has($linkedId) ) {

                $xf = $xfUsers->get($linkedId);
                $matchType = strtolower($xf->email) === $email ? 'explicit' : 'conflict';

                MigrationUserPlan::updateOrCreate(
                   ['wp_user_id' => $wp->wp_id],
                   [
                       'xf_user_id' => $linkedId,
                       'match_type' => $matchType,
                       'email' => $email,
                       'wp_username' => $wp->username,
                       'xf_username' => $xf->username,
                       'note' => $matchType === 'conflict' ? "E-Mail différent: {$xf->email}" : null,
                       'status' => $matchType === 'explicit' ? 'approved' : 'pending',
                   ]
                );
                $linkedXfIds[$linkedId] = true;
                return;
            }

            if( $linkedId && !$xfUsers->has($linkedId) ) {
                MigrationUserPlan::updateOrCreate(
                ['wp_user_id' => $wp->wp_id ],
                [
                    'match_type' => 'conflict',
                    'email' => $email,
                    'wp_username' => $wp->username,
                    'note' => "xf_user_id={$linkedId} introuvable",
                    'status' => 'approved'
                ]);
                return;
            }

            $candidates = $xfUsersByEmail->get($email,collect());

            if( $candidates->count() === 1 ){
                $xf = $candidates->first();
                MigrationUserPlan::updateOrCreate(
                    ['wp_user_id' => $wp->wp_id],
                    [
                        'xf_user_id' => $xf->user_id,
                        'match_type' => 'email',
                        'email' => $email,
                        'wp_username' => $wp->username,
                        'xf_username' => $xf->username,
                        'status' => 'pending'
                    ]
                );
                $linkedXfIds[$xf->user_id] = true;
                return;
            }

            if( $candidates->count() > 1 ){
                MigrationUserPlan::updateOrCreate(
                    ['wp_user_id' => $wp->wp_id ],
                    [
                        'match_type' => 'conflict',
                        'email' => $email,
                        'wp_username' => $wp->username,
                        'note' => "E-mail identique sur plusieurs comptes XF.",
                    ]
                );
                return;
            }

            MigrationUserPlan::updateOrCreate(
                ['wp_user_id' => $wp->wp_id ],
                [
                    'match_type' => 'wp_only',
                    'email' => $email,
                    'wp_username' => $wp->username,
                    'status' => 'approved'
                ]
            );
        });

        $this->info("Listing old XF accounts...");
        foreach( $xfUsers as $id => $xf ) {
            if( isset($linkedXfIds[$id]) ) {
                continue;
            }
            MigrationUserPlan::updateOrCreate(
                ['xf_user_id' => $xf->user_id, 'wp_user_id' => null],
                [
                    'match_type' => 'xf_only',
                    'email' => strtolower($xf->email),
                    'xf_username' => $xf->username,
                    'status' => 'approved'
                ]
            );
        }

        $pending = MigrationUserPlan::where('status', 'pending')->count();
        $this->newLine(2);
        $this->info("Plan generated. {$pending} pending cases.");
    }
}
