<?php

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use App\Models\Expertise;

use App\Events\Company\CreateSearchWorkerEvent;

class PopulateDummyCompany extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'Populate:company {--length=1} {--owner=1} {--projectmanager=1}  {--supervisor=1}  {--accountant=1} {--workers=1}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Populate Company and it\'s users requiring two parameters --length and --users --workers(numbers of users and workers on each company)';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $options = $this->options();
        $faker = \Faker\Factory::create();
        $validZipCodes = array('95035', '95002', '95056', '94035', '94022', '94025', '94002', '93907', '93610');
        $validZipCodeRadius = array(1, 5, 10, 15, 20, 25);

        // seeding of company
        for ($x = 0; $x <= (int) $options['length'] - 1; $x++) 
        {
            $expertises      = []; 
            $randomExpertise = Expertise::inRandomOrder()->first()->id;

            array_push($expertises, ['id' => $randomExpertise]);

            $randomValidZipCodes = array_rand($validZipCodes, 2);
            $zipCode = $validZipCodes[$randomValidZipCodes[0]];
            $company = \App\Models\Company::create(
                [
                    'name'                => $faker->company,
                    'contact_person_name' => $faker->name,
                    'contact_person_no'   => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'type'                => 'affiliated',
                    'company_tel'         => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'company_tel2'        => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'street_address'      => $faker->streetAddress,
                    'city'                => $faker->city,
                    'state'               => $faker->state,
                    'zipcode'             => $zipCode,
                    'expertises'          => json_encode($expertises),
                    'overhead_charge'     => 0,
                    'overhead_type'       => 'percent',
                    'email_address'       => md5(rand()) . $faker->unique()->email,
                    'email_verified_at'   => Carbon::now(),
                    'service_charge'      => '10',
                    'is_banned'           => 'false',
                ]);
            $this->info('Company ' . $company->name . ' has been saved successfully.');

            // seeding of company subscription
            $subscription = \App\Models\CompanySubscriptions::create([
                'subscription_rate_id' => 3,
                'company_id' => $company->id,
                'customer_id' => 'cus_IEFgW8ubzBgwBu',
                'invoice_no' => sprintf("%04d", $company->id) . '-' . sprintf("%02d", rand(1, 12)) . sprintf("%02d", rand(0, 30)) . sprintf("%02d", rand(0, 20)) . '-' . sprintf("%04d", rand(0, 9999)),
                'mode_of_payment' => 'yearly',
                'duration' => Carbon::now()->subDays(21)->addDays(365)->format('Y-m-d'),
                'date_subscribed' => Carbon::now()->subDays(21)->format('Y-m-d'),
                'rate' => 0,
                'current_month_paid' => Carbon::now()->subDays(21)->addDays(365)->format('Y-m-d'),
                'discount' => 0,
                'previous_bill' => 0,
                'current_bill' => 0,
                'penalty_charge' => 0,
                'amount_due' => 0,
                'amount_paid' => 0,
                'total_paid' => 0,
                'created_at' => Carbon::now(),
            ]);
            $this->info('---Subscription-> ' . $subscription->customer_id . ' has been saved successfully.');


            $IECData = [
                'company_id' => $company->id,
                'iec_number' => 'IEC-Code-sample',
                'chapter_name' => 'IEC-POPULATED',
            ];

            $IECTransaction = \App\Models\IECMembers::create($IECData);
            $this->info('---IEC Member-> ' . $IECTransaction->chapter_name . ' has been saved successfully.');

            $company_experience_array = [];
            $company_burden_rate_array = [];
            $experiences = \App\Models\Experience::get();
            foreach ($experiences as $experience) {
                array_push($company_experience_array,
                    \App\Models\CompanyExperience::create([
                        'company_id' => $company->id,
                        'name' => $experience->name,
                    ])->id
                );
                array_push($company_burden_rate_array,
                    \App\Models\CompanyBurdenRate::create([
                        'company_id' => $company->id,
                        'company_experience_id' => $company_experience_array[count($company_experience_array) - 1],
                        'burden_rate' => 10.0,
                        'burden_rate_type' => 'percent',
                    ])
                );
            }
            // seeding of company owner
            $companyOwnersAndAdmins = [];
            for ($uc = 0; $uc <= (int) $options['owner'] - 1; $uc++) {
                $worker = \App\Models\Worker::create([
                    'worker_id' => sprintf("%04d", $company->id) . '-' . date("mdy") . '-' . sprintf("%04d", $uc + 1),
                    'first_name' => $faker->firstName,
                    'last_name' => $faker->lastName,
                    'email_address' => $faker->unique()->email,
                    'password' => Hash::make('123456789'),
                    'email_verification_code' => md5(rand()),
                    'email_verified_at' => Carbon::now(),
                    'is_active' => '1',
                    'phone_num' => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'enable_2fa' => 'false',
                    'street_address' => $faker->streetAddress,
                    'city' => $faker->city,
                    'state' => $faker->state,
                    'zipcode' => $zipCode,
                    'rate' => 100,
                    'original_rate' => 100,
                    'overhead_amount' => 0,
                    'overhead_type' => 'percent',
                    'date_hired' => Carbon::now(),
                    'is_account_disabled' => 'false',
                ]);
                $this->info('---Owner/Admin-> ' . $worker->email_address . ' has been saved successfully.');
                \App\Models\CompanyUser::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'role_id' => 1, // owner
                ]);

                // create availabilities data
                $availabities = \App\Models\Availabilities::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'worker_type' => 'inhouse',
                    'rate' => 100,
                    'min_availability_date' => Carbon::now(),
                    'max_availability_date' => Carbon::now()->addDays(31)->addYears(10),
                ]);
                
                array_push($companyOwnersAndAdmins, $worker->id);

            }

            // seeding of company project mananger
            $companyProjectManagers = [];
            for ($uc = 0; $uc <= (int) $options['projectmanager'] - 1; $uc++) {
                $worker = \App\Models\Worker::create([
                    'worker_id' => sprintf("%04d", $company->id) . '-' . date("mdy") . '-' . sprintf("%04d", $uc + (count($companyOwnersAndAdmins) + 1)),
                    'first_name' => $faker->firstName,
                    'last_name' => $faker->lastName,
                    'email_address' => $faker->unique()->email,
                    'password' => Hash::make('123456789'),
                    'email_verification_code' => md5(rand()),
                    'email_verified_at' => Carbon::now(),
                    'is_active' => '1',
                    'phone_num' => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'enable_2fa' => 'false',
                    'street_address' => $faker->streetAddress,
                    'city' => $faker->city,
                    'state' => $faker->state,
                    'zipcode' => $zipCode,
                    'rate' => 100,
                    'original_rate' => 100,
                    'overhead_amount' => 0,
                    'overhead_type' => 'percent',
                    'date_hired' => Carbon::now(),
                    'is_account_disabled' => 'false',
                ]);
                $this->info('---Project Manager-> ' . $worker->email_address . ' has been saved successfully.');
                \App\Models\CompanyUser::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'role_id' => 2, // project manager
                ]);

                // create availabilities data
                $availabities = \App\Models\Availabilities::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'worker_type' => 'inhouse',
                    'rate' => 100,
                    'min_availability_date' => Carbon::now(),
                    'max_availability_date' => Carbon::now()->addDays(31)->addYears(10),
                ]);

                array_push($companyProjectManagers, $worker->id);
            }

            // seeding of company supervisor
            $companySupervisors = [];
            for ($uc = 0; $uc <= (int) $options['supervisor'] - 1; $uc++) {
                $worker = \App\Models\Worker::create([
                    'worker_id' => sprintf("%04d", $company->id) . '-' . date("mdy") . '-' . sprintf("%04d", $uc + (count($companyOwnersAndAdmins) + count($companyProjectManagers) + 1)),
                    'first_name' => $faker->firstName,
                    'last_name' => $faker->lastName,
                    'email_address' => $faker->unique()->email,
                    'password' => Hash::make('123456789'),
                    'email_verification_code' => md5(rand()),
                    'email_verified_at' => Carbon::now(),
                    'is_active' => '1',
                    'phone_num' => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'enable_2fa' => 'false',
                    'street_address' => $faker->streetAddress,
                    'city' => $faker->city,
                    'state' => $faker->state,
                    'zipcode' => $zipCode,
                    'rate' => 100,
                    'original_rate' => 100,
                    'overhead_amount' => 0,
                    'overhead_type' => 'percent',
                    'date_hired' => Carbon::now(),
                    'is_account_disabled' => 'false',
                ]);
                $this->info('---Supervisor-> ' . $worker->email_address . ' has been saved successfully.');
                \App\Models\CompanyUser::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'role_id' => 3, // supervisor
                ]);

                // create availabilities data
                $availabities = \App\Models\Availabilities::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'worker_type' => 'inhouse',
                    'rate' => 100,
                    'min_availability_date' => Carbon::now(),
                    'max_availability_date' => Carbon::now()->addDays(31)->addYears(10),
                ]);

                array_push($companySupervisors, $worker->id);
            }

            // seeding of company accountant
            $companyAccountants = [];
            for ($uc = 0; $uc <= (int) $options['accountant'] - 1; $uc++) {
                $worker = \App\Models\Worker::create([
                    'worker_id' => sprintf("%04d", $company->id) . '-' . date("mdy") . '-' . sprintf("%04d", $uc + (count($companyOwnersAndAdmins) + count($companyProjectManagers) + 1)),
                    'first_name' => $faker->firstName,
                    'last_name' => $faker->lastName,
                    'email_address' => $faker->unique()->email,
                    'password' => Hash::make('123456789'),
                    'email_verification_code' => md5(rand()),
                    'email_verified_at' => Carbon::now(),
                    'is_active' => '1',
                    'phone_num' => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'enable_2fa' => 'false',
                    'street_address' => $faker->streetAddress,
                    'city' => $faker->city,
                    'state' => $faker->state,
                    'zipcode' => $zipCode,
                    'rate' => 100,
                    'original_rate' => 100,
                    'overhead_amount' => 0,
                    'overhead_type' => 'percent',
                    'date_hired' => Carbon::now(),
                    'is_account_disabled' => 'false',
                ]);
                $this->info('---Supervisor-> ' . $worker->email_address . ' has been saved successfully.');
                \App\Models\CompanyUser::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'role_id' => 4, // accountant
                ]);

                // create availabilities data
                $availabities = \App\Models\Availabilities::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'worker_type' => 'inhouse',
                    'rate' => 100,
                    'min_availability_date' => Carbon::now(),
                    'max_availability_date' => Carbon::now()->addDays(31)->addYears(10),
                ]);

                array_push($companyAccountants, $worker->id);
            }

            // seeding of company worker
            $companyWorkers = [];
            $companyWorkerNames = [];
            $workerAvailabities = [];
            for ($uc = 0; $uc <= (int) $options['workers'] - 1; $uc++) {
                $firstName = $faker->firstName;
                $lastLame = $faker->lastName;

                $worker = \App\Models\Worker::create([
                    'worker_id' => sprintf("%04d", $company->id) . '-' . date("mdy") . '-' . sprintf("%04d", $uc + (count($companyOwnersAndAdmins) + count($companyProjectManagers) + count($companySupervisors) + count($companyAccountants) + 1)),
                    'first_name' => $firstName,
                    'last_name' => $lastLame,
                    'email_address' => $faker->unique()->email,
                    'password' => Hash::make('123456789'),
                    'email_verification_code' => md5(rand()),
                    'email_verified_at' => Carbon::now(),
                    'is_active' => '1',
                    'phone_num' => '+1' . str_replace(array('-', '(', ')', ' ', '.'), '', $faker->tollFreePhoneNumber),
                    'enable_2fa' => 'false',
                    'street_address' => $faker->streetAddress,
                    'city' => $faker->city,
                    'state' => $faker->state,
                    'zipcode' => $zipCode,
                    'rate' => 100,
                    'flat_rate' => 100,
                    'overhead_amount' => 0,
                    'overhead_type' => 'percent',
                    'date_hired' => Carbon::now(),
                    'is_account_disabled' => 'false',
                    'distance' => $validZipCodeRadius[array_rand($validZipCodeRadius, 1)],
                ]);

                array_push($companyWorkers, $worker->id);
                array_push($companyWorkerNames, $worker->first_name . ' ' . $worker->last_name);

                $this->info('---worker---> ' . $worker->worker_id . ' has been saved successfully.');
                $experience_rand_id = $company_experience_array[rand(0, count($company_experience_array) - 1)];
                $burden_rate_rand = array_search($experience_rand_id, array_column($company_burden_rate_array, 'company_experience_id'));
                \App\Models\WorkerExperience::create([
                    'experience_id' => $experience_rand_id,
                    'burden_rate_id' => $company_burden_rate_array[$burden_rate_rand]->id,
                    'expertise_id' => 1,
                    'worker_id' => $worker->id,
                    'is_worker' => 1,
                ]);
                $companyUser = \App\Models\CompanyUser::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'role_id' => 5, // worker
                    'availability_status' => 'for-lease',
                ]);
                
                \App\Models\WorkAreaLists::create([
                    'work_area_id' => 1,
                    'worker_id' => $worker->id,
                    'worker_type' => 'worker',
                ]);

                $availabities = \App\Models\Availabilities::create([
                    'worker_id' => $worker->id,
                    'company_id' => $company->id,
                    'worker_type' => 'inhouse',
                    'rate' => 100,
                    'min_availability_date' => Carbon::now(),
                    'max_availability_date' => Carbon::now()->addDays(31)->addYears(10),
                ]);
                array_push($workerAvailabities, $availabities->id);
                event(new CreateSearchWorkerEvent($companyUser)); //Event for creating search data for worker
            }

            // seeding of company project
            // $randomProjectManagers = $companyProjectManagers[array_rand($companyProjectManagers)];
            // $project = \App\Models\Projects::create([
            //     'company_id' => $company->id,
            //     'project_manager_id' => $randomProjectManagers,
            //     'name' => 'Project 101',
            //     'description' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
            //     'additional_info' => 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.',
            //     'location' => '{"street_address":"123","city":"Milpitas Avenue","state":"California","zipcode":"95035"}',
            //     'worker_items' => '["PPE","Safety gear"]',
            //     'clock_in' => '09:00:00',
            //     'clock_out' => '18:00:00',
            //     'date_start' => Carbon::now(),
            //     'date_end' => Carbon::now()->addDays(90),
            // ]);
            // \App\Models\ProjectSupervisors::create([
            //     'user_id' => $companySupervisors[0],
            //     'project_id' => $project->id,
            //     'date_from' => Carbon::now(),
            //     'date_to' => Carbon::now()->addDays(30),
            // ]);
            // for ($uc = 0; $uc <= (int) $options['workers'] - 1; $uc++) {
            //     $assignedWorkers = \App\Models\AssignedWorkers::create([
            //         'project_id' => $project->id,
            //         'worker_id' => $companyWorkers[$uc],
            //         'created_at' => Carbon::now(),
            //     ]);
            //     $assignedAvailability = \App\Models\AssignedAvailability::create([
            //         'availability_id' => $workerAvailabities[$uc],
            //         'assigned_worker_id' => $assignedWorkers->id,
            //         'start_date' => Carbon::now(),
            //         'end_date' => Carbon::now()->addDays(30),
            //     ]);
            //     for ($day = 0; $day < 30; $day++) {
            //         \App\Models\ProjectWorkersTimesheet::create([
            //             'project_worker_id' => $assignedWorkers->id,
            //             'worker_id' => $companyWorkers[$uc],
            //             'total_hours' => 0,
            //             'date' => Carbon::now()->addDays($day),
            //             'time_in' => '09:00:00',
            //             'time_out' => '18:00:00',
            //             'status' => 'pending',
            //             'request_modification_message' => null,
            //             'requested_by' => $companyWorkerNames[$uc],
            //             'approved_by' => null,
            //         ]);
            //     }
            // }
        }

        $this->info('Default password for users is 123456789');
        return 0;
    }
}
