<?php

namespace App\Console\Commands;

use App\Enums\DbStatusFieldEnum;
use App\Models\Contact;
use App\Models\ProfitCenter;
use App\Models\Role;
use App\Models\User;
use Illuminate\Console\Command;

class EmegrendelesimportProfitCenterWithUsers extends Command
{
    private string $defaultFile = 'profitCenterWithUser.php';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'emegrendeles:importProfitCenterWithUsers {--file= : default database/import/*defaultFile*}
        {--doc : print documentation }';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'ProfitCenter import with user';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->signature = str_replace('*defaultFile*', $this->defaultFile, $this->signature);
        parent::__construct();
    }

    public function printDoc()
    {
        $this->info("
1: source malvac.e98.hu localhost -  fs.emegrendeles.hu -  felhasznalo
2: sql Select:
SELECT
f.kod id,
f.nev userName,
f.jelszo userPassword,
k_email userEmail,
f.statusz,
fa.nev name,
fa.irsz postCode,
fa.varos city,
fa.cim street,
fa.megjegy note,
k_email email,
k_tel phone,
k_mob mobil,
k_nev contactName,
k_email contactEmail,
k_tel contactPhone,
k_mob contactMobil
FROM `felhasznalo` as f
left join felhasznalo_adat fa  on fa.kod=f.kod
WHERE f.`statusz`='F'
order by name
3: export json
        ");

        return 0;
    }

    /**
     * From https://stackoverflow.com/a/19136663/319266
     */
    public function stripComments(string $str = '')
    {
        $str = preg_replace('!/\*.*?\*/!s', '', $str);
        $str = preg_replace('/\n\s*\n/', "\n", $str);

        return $str;
    }

    private function stripPrefixedItemFromArray($data, $prefix)
    {
        if (is_array($prefix)) {
            foreach ($prefix as $pre) {
                $data = $this->stripPrefixedItemFromArray($data, $pre);
            }
        } else {
            foreach ($data as $k => $v) {
                if (strpos($k, $prefix) !== false) {
                    unset($data[$k]);
                }
            }
        }

        return $data;
    }

    private function getPrefixKeyedDataFromArray($data, $prefix)
    {
        $retArray = [];
        foreach ($data as $k => $v) {
            if (strpos($k, $prefix) !== false) {
                $key = str_replace($prefix, '', $k);
                $key = lcfirst($key);
                $retArray[$key] = $v;
            }
        }

        return $retArray;
    }

    private function getUserDataFromArray($data)
    {
        $userData = $this->getPrefixKeyedDataFromArray($data, 'user');
        $userData['password'] = \Hash::make($userData['password']);

        return $userData;
    }

    private function getContactDataFromArray($data)
    {
        return $this->getPrefixKeyedDataFromArray($data, 'contact');
    }

    private function getAcceptedProfitCenterData($data)
    {
        $acceptedKey = [
            'name',
            'hooreycaId',
            'nameId',
            'email',
            'postCode',
            'city',
            'street',
            'phone',
            'mobil',
            'note',
        ];
        $retData = [];
        foreach ($data as $k => $v) {
            if (in_array($k, $acceptedKey)) {
                $retData[$k] = $v;
            }
        }

        return $retData;
    }

    private function fillNeedProfitCenterData($data,
        $num = null,
        ?bool $convertNull = true)
    {
        if (! $num) {
            $num = random_int(1000, 9999);
        }
        $data = $this->getAcceptedProfitCenterData($data);
        if (! isset($data['hooreycaId'])) {
            $data['hooreycaId'] = 'H'.$num;
        }
        if ($convertNull) {
            foreach ($data as $k => $v) {
                if ($v === '') {
                    $data[$k] = null;
                }
            }
        }
        $data['status'] = DbStatusFieldEnum::active;

        return $data;
    }

    private function getAcceptedContactData($data)
    {
        $acceptedKey = [
            'name',
            'email',
            'phone',
            'note',
        ];
        if (isset($data['mobil']) && ! is_null($data['mobil']) && $data['mobil'] !== '') {
            $data['phone'] = $data['mobil'];
        }
        $retData = [];
        foreach ($data as $k => $v) {
            if (in_array($k, $acceptedKey)) {
                $retData[$k] = $v;
            }
        }

        return $retData;
    }

    private function fillNeedContactData($data,
        $num = null,
        ?bool $convertNull = true)
    {
        $data = $this->getAcceptedContactData($data);
        if ($convertNull) {
            foreach ($data as $k => $v) {
                if ($v === '') {
                    $data[$k] = null;
                }
            }
        }
        $data['status'] = DbStatusFieldEnum::active;

        return $data;
    }

    private function createUser($userData)
    {
        if ($user = User::where('email', $userData['email'])->first()) {
            $emailPieces = explode('@', $userData['email']);
            $userData['email'] = $emailPieces[0].time().'@'.$emailPieces[1];
            $this->error('Presents user:'.$userData['name'].'  rename email:'.$userData['email']);
            /*            print var_export($userData,true);
                        print var_export($user->toArray(),true);
                        die();*/
        } else {
        }
        $user = User::Create($userData);
        $this->info('User created:'.$user->name);

        return $user;
    }

    private ?Role $RoleProfitCenter = null;

    private function initProfitCenterRole()
    {
        $this->RoleProfitCenter = Role::where('name', 'profit-center')->first();
    }

    public function importFile($file, $format = 'JSON')
    {
        $this->initProfitCenterRole();
        $this->info('inport fileName:'.$file.' format'.$format);
        $file = base_path().DIRECTORY_SEPARATOR.'database'.DIRECTORY_SEPARATOR.'import'.DIRECTORY_SEPARATOR.$file;
        $this->info('file:'.$file);

        switch ($format) {
            case 'JSON':
                try {
                    // json_decode("{", false, 512, JSON_THROW_ON_ERROR);
                    $jsonStr = $this->stripComments(file_get_contents($file));
                    $jsonStr = ltrim($jsonStr);
                    $itemsArray = json_decode($jsonStr, true, 512, JSON_THROW_ON_ERROR);
                } catch (\JsonException $exception) {
                    echo $exception->getMessage(); // displays "Syntax error"
                    exit();
                }
                break;
            case 'PHP':
                require_once $file;
                $itemsArray = $f;
                break;
        }
        auth()->loginUsingId(1);

        foreach ($itemsArray as $k => $item) {

            /*
             array (
  'id' => 182,
  'userName' => 'atrium',
  'userPass' => 'atriumetterem',
  'statusz' => 'F',
  'name' => 'Átrium',
  'postCode' => 1138,
  'city' => 'Budapest',
  'street' => 'Váci út 45.',
  'note' => '',
  'contactName' => 'Szőnyi Iván',
  'contactEmail' => 'atrium@eurest.hu',
  'contactPhone' => '',
  'contactMobil' => '06-30/207-0148',
)
             */
            $userData = $this->getUserDataFromArray($item);
            $contactData = $this->getContactDataFromArray($item);
            /*
                        print var_export($item,true);
            */

            $profitCenterData = $this->stripPrefixedItemFromArray($item, ['user', 'contact']);
            $profitCenterData = $this->fillNeedProfitCenterData($profitCenterData, $k + 1);
            $ProfitCenter = ProfitCenter::create($profitCenterData);
            $contactData = $this->fillNeedContactData($contactData);
            $Contact = Contact::create($contactData);
            $this->info('Contact created:'.$Contact->name);
            $User = $this->createUser($userData);
            $User->syncRolesWithoutDetaching([$this->RoleProfitCenter]);
            $ProfitCenter->users()->syncWithoutDetaching($User);
            $ProfitCenter->syncContactRelations([$Contact->id]);
            $this->info('ProfitCenter created:'.$ProfitCenter->name);

        }
        // $this->info(var_export($Json,true));

    }

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        // $name = $this->argument('name');
        if ($this->option('doc')) {
            return $this->printDoc();
        }
        $file = $this->defaultFile;
        if ($this->option('file')) {
            $file = $this->option('file');
        }
        $this->importFile($file, 'PHP');
        $this->info('Import End');

        return 0;
    }
}
