<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use App\Modules\Bookings\Repair;
use App\Microsoft\Dynamics\CrmAuth;
use App\Microsoft\Dynamics\CrmAuthenticationHeader;
use App\Microsoft\Dynamics\CrmExecuteSoap;
use App\Microsoft\Dynamics\CrmDynamicsPHP;
use App\Modules\Clients\Client;
use App\Modules\Clients\Customer;
use App\Config;
use App\Modules\Clients\SiteUser;
use App\Console\Commands\AbstractCommand;
// protected $fillable = ['site_id', 'first_name', 'last_name', 'email', 'phone', 'mobile', 'position', 'authority'];


class SyncToDynamics extends Command
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'sync:todynamics';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "Sync clients and customers to dynamics crm online accounts and contacts if they don't have a dynamics_id.";

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

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        $url = env('DYNAMICS_URL');
        $username = env('DYNAMICS_CRM_USERNAME');
        $password = env('DYNAMICS_CRM_PASSWORD');

        $this->info("Logging in with username: " . $username . " and this url:" . $url);
        $crmDynamics = new CrmDynamicsPHP($username, $password, $url);
        $userid = $crmDynamics->crmAuth->WhoAmI();
        $this->info("Received UserId: " . $userid);
        if ($userid != null) {
            $this->info("Trying to receive username from userId: " . $userid);
            $name = $crmDynamics->crmAuth->GetUserName($userid);
            $this->info("Retrived this username: " . $name);
        } else {
            $this->error("Could not login");
            return;
        }

        $this->syncClientsToDynamicAccounts($crmDynamics);
        $this->syncCustomerstoDynamicContacts($crmDynamics);



    }


    function syncCustomerstoDynamicContacts($crmDynamics)
    {
      $this->info('Logged in now. Finding list of clients who are not synced with Dynamics online');
      $customers = Customer::whereNull('dynamics_id')
      ->orderby('id', 'desc')
      ->get();
      $this->info("Found this many customer to get accounts for: " . count($customers));
      $bar = $this->output->createProgressBar(count($customers));
      $countClientSync = 0;
      foreach ($customers as $customer) {

          $this->info("Getting account for " . $customer->name);
          $data = [
              'firstname'           => $customer->first_name,
              'lastname'            => $customer->last_name,
              'emailaddress1'       => $customer->email,
              'telephone1'          => $customer->phone,
              'mobilephone'         => $customer->mobile,
              'telephone2'          => $customer->phone2,
              'address1_line1'      => $customer->address,
              'address1_line2'      => $customer->address2,
              'address1_county'     => $customer->county,
              'address1_city'       => $customer->town,
              'address1_postalcode' => $customer->postcode,
              'new_seraph_id'       => $customer->id,
              'new_seraph_model'    => 'customer',
          ];

          $typeOverrides = array('new_seraph_id' => 'int');

          $dynamics_id = $crmDynamics->contacts->createContact($data, $typeOverrides);
          //$createAccountResponse = $crmAuth->createAccountFromClient("test", "test","test", $data);
          $this->info("Retreived Dynamics ID: " . $dynamics_id . " for " . $customer->name);
          $customer->dynamics_id = $dynamics_id;
          $customer->save();
          $this->info("Saved Dynamics ID: " . $dynamics_id . " to " . $customer->name);
          $countClientSync++;
          $bar->advance();
         /* if($countClientSync == 3)
          {
            die();
          }*/


      }
      $bar->finish();
      $this->info('Finished sync');
    }

    function syncClientsToDynamicAccounts($crmDynamics)
    {
      $this->info('Logged in now. Finding list of clients who are not synced with Dynamics online');
      $clients = Client::whereNull('dynamics_id')
      ->orderby('id', 'desc')
      ->get();
    //$clients = Client::find(1)->toArray();
      $this->info("Found this many clients to get accounts for: " . $clients->count());
      $bar = $this->output->createProgressBar($clients->count());
      $countClientSync = 0;
      foreach ($clients as $client) {

          $this->info("Getting account for " . $client->name);

          $data = [
              'name' => $client->name,
              'websiteurl' => $client->website,
              'new_seraph_id' => $client->id,
          ];

          if ($site = $client->sites()->has('users')->first()) {
              $data = array_merge($data, [
                  'address1_line1' => $site->address,
                  'address1_city' => $site->address2,
                  'address1_postalcode' => $site->postcode,
                  'address1_telephone1' => $site->primary_phone,
                  'telephone1' => $site->primary_phone,
              ]);
          }

          if ($site && $siteUser = $site->users()->first()) {
              $data = array_merge($data, [
                  'emailaddress1' => $siteUser->email,
              ]);
          }


          $typeOverrides = array('new_seraph_id' => 'int');

          $dynamics_id = $crmDynamics->accounts->createAccount($data, $typeOverrides);
          //$createAccountResponse = $crmAuth->createAccountFromClient("test", "test","test", $data);
          if($dynamics_id) {
              $this->info("Retreived Dynamics ID: " . $dynamics_id . " for " . $client->name);
              $client->dynamics_id = $dynamics_id;
              $client->save();
              $this->info("Saved Dynamics ID: " . $dynamics_id . " to " . $client->name);
              $countClientSync++;
              $bar->advance();

              $sites = $client->sites()->has('users')->get();
              foreach($sites as $site){
                  if ($site && $siteUsers = $site->users()->get()) {
                      //   dd($siteUsers);
                      $this->info("\nFound this many site users to sync to the parent account (". $client->name .") : " . $siteUsers->count());
                      foreach ($siteUsers as $user) {
                          $site = $user->site;
                          $this->info("\nSyncing site users");
                          $this->info("\nGetting account for " . $user->first_name . " " . $user->last_name . " at " . $client->name);
                          $data = [
                              'firstname'           => $user->first_name,
                              'lastname'            => $user->last_name,
                              'emailaddress1'       => $user->email,
                              'telephone2'          => $user->phone,
                              'mobilephone'         => $user->mobile,
                              'new_seraph_id'       => $user->id,
                              'new_seraph_model'    => 'siteuser',
                              'parentcustomerid'    => $dynamics_id,
                              'telephone1'          => $site->primary_phone,
                              'address1_line1'      => $site->address,
                              'address1_city'       => $site->address2,
                              'address1_postalcode' => $site->postcode,
                          ];
                          $typeOverrides = array('new_seraph_id' => 'int', 'parentcustomerid' => 'lookup');
                          $siteUserDynamicsId = $crmDynamics->contacts->createContact($data, $typeOverrides);
                          $user->dynamics_id = $siteUserDynamicsId;
                          $user->save();
                      }
                  }
              }
          }
          else {
              // no dynamics id error
          }






          /*if($countClientSync == 3)
          {
            die();
          }
		*/

      }
      $bar->finish();
      $this->info('Finished sync');
    }

    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return [

        ];
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [
            ['summary', 's', InputArgument::OPTIONAL, 'Indicate if the remainder is a standar or all one. The possible modes are:\n
    -standard, the notifications will be send for all the open tasks not marked as eclude from notifications.
    -all, the notifications will be send for all the open tasks', 'standard'],
        ];
    }

    protected function remote_get_contents($url)
    {
        if (function_exists('curl_get_contents') and function_exists('curl_init')) {
            return $this->curl_get_contents($url);
        } else {
            // A litte slower, but (usually) gets the job done
            return file_get_contents($url);
        }
    }

    protected function curl_get_contents($url)
    {
        // Initiate the curl session
        $ch = curl_init();

        // Set the URL
        curl_setopt($ch, CURLOPT_URL, $url);

        // Removes the headers from the output
        curl_setopt($ch, CURLOPT_HEADER, 0);

        // Set the timeout
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);

        // Return the output instead of displaying it directly
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // Execute the curl session
        $output = curl_exec($ch);

        // Close the curl session
        curl_close($ch);

        // Return the output as a variable
        return $output;
    }

    /**
     * Returns an array containing all the site users
     * for the given client.
     *
     * @param  \App\Modules\Clients\Client $client
     * @return array
     */
    protected function getSiteUsers($client)
    {
        return $client->sites->map(function($site) {
            return $site->users->flatMap(function($user) use ($site) {
                return [
                    'firstname'           => $user->first_name,
                    'lastname'            => $user->last_name,
                    'emailaddress1'       => $user->email,
                    'telephone1'          => $user->phone,
                    'mobilephone'         => $user->mobile,
                    'address1_line1'      => $site->address,
                    'address1_city'       => $site->address2,
                    'address1_postalcode' => $site->postcode,
                ];
            });
        })->reject(function($user) {
            return $user->isEmpty();
        })->toArray();
    }
}
