<?php

namespace App\Core\Helper;

use DateTime;
use Illuminate\Support\Facades\App;


class PhpHelper {

    private static $days = [
        'Pazartesi',
        'Salı',
        'Çarşamba',
        'Perşembe',
        'Cuma',
        'Cumartesi',
        'Pazar',
    ];
    private static $months = [
        'Ocak',
        'Şubat',
        'Mart',
        'Nisan',
        'Mayıs',
        'Haziran',
        'Temmuz',
        'Ağustos',
        'Eylül',
        'Ekim',
        'Kasım',
        'Aralık',
    ];
    private static $encryptionKey = 'd0a7e7997b6d5fcd55f4b5c32611b87cd923e88837b63bf2941ef819dc8ca282';

    public static function json_decode($input) {
        return json_decode($input);
    }

    public static function json_encode($input) {
        return json_encode($input);
    }

    public static function pre($input) {
        echo '<pre>';
        print_r($input);
        echo '</pre>';
    }

    /**
     * Display the difference between two dates
     * (30 years, 9 months, 25 days, 21 hours, 33 minutes, 3 seconds).
     *
     * @param string $start     starting date
     * @param string $end=false ending date
     *
     * @return string formatted date difference
     */
    public static function dateDiff($start, $end = false) {$return = [];

        try {
            $start = new DateTime($start);
            $end = new DateTime($end);
            $form = $start->diff($end);
        } catch (Exception $e) {
            return $e->getMessage();
        }

        $display = ['y' => 'Yıl', 'm' => 'Ay', 'd' => 'Gün', 'h' => 'Saat', 'i' => 'Dakika', 's' => 'Saniye'];

        foreach ($display as $key => $value) {
            if ($form->$key > 0) {
                $return[] = $form->$key . ' ' . $value;
            }
        }

        return implode($return, ', ');
    }

    /**
     * Display the day count between two dates
     * (3 days).
     *
     * @param string $start     starting date
     * @param string $end=false ending date
     *
     * @return string day count
     */
    public static function dayCount($end, $start) {
        $return = [];

        try {
            $start = new DateTime($start);
            $end = new DateTime($end);
            $form = $start->diff($end);
        } catch (Exception $e) {
            return $e->getMessage();
        }

        return $form->days;
    }

    /**
     * Display the day and month name
     * (16 July).
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function dayNumberAndMonthWord($date) {
        return date('d', strtotime($date)) . ' ' . self::$months[date('m', strtotime($date)) - 1];
    }

    /**
     * Display the month name
     * (July).
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function monthName($date) {
        return self::$months[date('m', strtotime($date)) - 1];
    }

    /**
     * Display the day name
     * (Sunday).
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function dayName($date) {
        return self::$days[date('N', strtotime($date)) - 1];
    }

    /**
     * Display the day number
     * 01.
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function dayNumber($date) {
        return date('d', strtotime($date));
    }

    /**
     * Display the human readable day
     * 01.
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function humanReadableDateWithDay($date) {
        return date('d', strtotime($date)) . ' ' . self::$months[date('m', strtotime($date)) - 1] . ' ' . date('Y', strtotime($date)) . ', ' . self::dayName($date);
    }

    /**
     * Display the human readable day
     * 01.
     *
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function humanReadableDate($date) {
        return date('d-m-Y H:i:s', strtotime($date));
    }

    public static function humanReadableDateWithoutClock($date) {
        return date('d-m-Y', strtotime($date));
    }

    /**
     * @param string $date date
     *
     * @return string formatted date
     */
    public static function sqlDate($date) {
        $date = date('Y-m-d', strtotime($date));

        return $date;
    }

    public static function getMonth() {
        return self::$months;
    }

    public static function isValidDate($date) {
        if (!is_string($date)) {
            return false;
        }
        $day = substr($date, 0, 2);
        $mont = substr($date, 3, 2);
        $year = substr($date, 6, 4);
        return checkdate($mont, $day, $year);
    }

    public static function fillNullIfEmpty(&$variable) {
        if (!isset($variable)) {
            $variable = null;
        }
        return $variable;
    }

    public static function getWeekDays() {
        $days = self::$days;
        $result = array();
        $counter = 1;
        foreach ($days as $x) {
            $result[$counter] = $x;
            $counter++;
        }
        return $result;
    }

    public static function parseXmlToArray($xmlSource) {
        try {
            $xmlOut = simplexml_load_string($xmlSource, 'SimpleXMLElement', LIBXML_NOCDATA);

            $arrayOut = json_decode(json_encode($xmlOut), true);
        } catch (\Exception $e) {
            $arrayOut = false;
        }
        return $arrayOut;
    }

    public static function encryptCodeNumber($string, $key) {
        $key = is_null($key) ? self::$encryptionKey : $key;

        $result = '';
        for ($i = 0; $i < mb_strlen($string, "UTF-8"); $i++) {
            $char = mb_substr($string, $i, 1, "UTF-8");
            $keychar = mb_substr($key, ($i % mb_strlen($key, "UTF-8")) - 1, 1, "UTF-8");
            $char = chr(ord($char) + ord($keychar));
            $result.=$char;
        }
        $result = base64_encode($result);
        $result = str_replace("=", "", $result);
        return urlencode($result);
    }

    public static function decryptCodeNumber($string, $key) {
        $key = is_null($key) ? self::$encryptionKey : $key;

        $string = urldecode($string);
        $eqcount = strlen($string) % 4;
        if ($eqcount == 2)
            $string . "==";
        else if ($eqcount == 3)
            $string . "=";
        $result = '';
        $string = base64_decode($string);
        for ($i = 0; $i < mb_strlen($string); $i++) {
            $char = mb_substr($string, $i, 1);
            $keychar = mb_substr($key, ($i % mb_strlen($key)) - 1, 1);
            $char = chr(ord($char) - ord($keychar));
            $result.=$char;
        }
        return $result;
    }

    public static function generateRandomString($length = 5) {
        $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }


    public static function convertArrayToCsv (array $valueArray )
    {
        if ( !$valueArray )
        {
            return false;
        }
        $csvResult = "";

        $valueArray = singleElementArray($valueArray);

        /*Get The Column Names*/
        $firstArray = reset($valueArray);

        $csvResult.=implode(",",array_keys($firstArray))."\r\n";

        foreach ($valueArray as $perArray)
        {
            $csvResult.=implode(",",$perArray)."\r\n";
        }
        return $csvResult;
    }

    private static function nextExcelColName ( $colName = null )
    {
        $primary = range("A","Z");
        if ( !$colName)
        {
            return reset($primary);
        }

        if(last($primary) == $colName)
        {
            return reset($primary);
        }

        return $primary[array_search($colName,$primary)+1];

    }

    /* If $params[keyNames] is Empty Function Gonna Take All The Keys Of The Array */
    public static function convertArrayToXls (array $valueArray,array $params = [] )
    {
        try
        {
            $excel = App::make('excel');
            $params[ "fileName" ] = isset( $params[ "fileName" ] ) ? $params[ "fileName" ] : "xls_file";
            $params[ "pagePrefix" ] = isset( $params[ "pagePrefix" ] ) ? $params[ "pagePrefix" ] : "Page";
            $params[ "onlyTheseKeys" ] = isset( $params[ "onlyTheseKeys" ] ) ? $params[ "onlyTheseKeys" ] : [];
            $params[ "keyNames" ] = isset( $params[ "keyNames" ] ) ? $params[ "keyNames" ] : [];
            $result = $excel->create ( $params[ "fileName" ], function ( $excel ) use ( $valueArray, $params )
            {
                $excel->sheet ( $params[ "pagePrefix" ], function ( $sheet ) use ( $valueArray, $params)
                {
                    $rowCounter = 1;
                    $sheet->setOrientation ( 'landscape' );
                    if ($params["keyNames"])
                    {
                        $colCounter = 0;

                        foreach ($params["keyNames"] as $perKey)
                        {
                            if ($params["onlyTheseKeys"] && !in_array($perKey,$params["onlyTheseKeys"]))
                            {
                                continue;
                            }
                            $sheet->setCellValueByColumnAndRow ( $colCounter, $rowCounter, $perKey );
                            $style = array(
                                'alignment' => array(
                                    'horizontal' => "center",
                                )
                            );

                            $sheet->getDefaultStyle()->applyFromArray($style);
                            $colCounter++;
                        }
                        $rowCounter++;
                    }

                    foreach ($valueArray as $perValue)
                    {
                        $colCounter = 0;
                        foreach ($perValue as $perCol)
                        {
                            if ($params["onlyTheseKeys"] && !in_array($perKey,$params["onlyTheseKeys"]))
                            {
                                continue;
                            }
                            if (is_array($perCol))
                            {
                               $perCol = json_encode($perCol);
                            }
                            $sheet->setCellValueByColumnAndRow ( $colCounter, $rowCounter, $perCol );
                            $colCounter++;
                        }
                        $rowCounter++;
                    }

                } );

            });
            return $result;
        } catch ( Exception $e )
        {
            return null;
        }

    }

    public static function singleElementArray ( $arrayElement,array $extraParams = null)
    {
        $isMultiArray = true;

        if ( !is_array($arrayElement))
        {
            return [];
        }

        foreach ($arrayElement as $perItem)
        {
            if (gettype($perItem)!="array")
            {
                $isMultiArray = false;
                break;
            }
        }

        if(!$isMultiArray)
        {
            $isMultiArray = true;
            foreach (array_keys ( $arrayElement ) as $perKey)
            {
                if (!is_numeric($perKey))
                {
                    $isMultiArray = false;
                    break;
                }
            }
        }


        return $isMultiArray?$arrayElement:array($arrayElement);

    }

    public static function checkWizardMenu($wizardArray, $menuCode)
    {
        return array_filter($wizardArray, function ($key) use ($menuCode) {
            return $key['menu_code'] == $menuCode ? true : false;
        }, ARRAY_FILTER_USE_BOTH);
    }


    /*If its an array enter the index of the array to $index variable*/
    public static function fillOnUndefined($variable,$index = null,$fillWith = null,$arrayDelimiter = ".")
    {
        if ( !$arrayDelimiter)
        {
            return null;
        }

        $index = trim($index,$arrayDelimiter);

        if ( !$index && $index !== '0')
        {
            return false;
        }

        $indexes = explode($arrayDelimiter,$index);

        $arrayDeep = $variable;

        foreach ($indexes as $perIndex)
        {
            if ( !isset($arrayDeep[$perIndex]))
            {
                return $fillWith;
            }

            $arrayDeep = $arrayDeep[$perIndex];
        }

        return $arrayDeep;
    }
    public static function hexToBinary ( $hex )
    {
        if ( strlen($hex)<=0)
        {
            return null;
        }
        $str = "";
        for($i=0;$i<strlen($hex);$i+=2)
            $str .= chr(hexdec(substr($hex,$i,2)));

        return $str;
    }

    public static function  pickItemFromArray($index,array $targetArray)
    {
        try
        {
            $result = [ ];
            foreach ($targetArray as $perIndex => $perValue)
            {
                if (isset($perValue[$index]))
                {
                    $result[] = $perValue[$index];
                }

            }
            return $result;
        } catch ( Exception $e )
        {
            return [];
        }
    }

    public static function pickNodeFromArray($index, $value, array $targetArray)
    {
        try {
            $result = [];
            foreach ($targetArray as $perIndex => $perValue) {
                if (isset($perValue[$index]) && $perValue[$index] == $value) {
                    $result = $perValue;
                    break;
                }
            }
            return $result;
        } catch (Exception $e) {
            return [];
        }
    }

    public static function numberSortTurkish($number)
    {
        $returnString = '';
        $numberValue = [
            'inci' => [1,5,8,20,70,80],
            'üncü' => [3,4,100],
            'nci' => [2,7,50],
            'ıncı' => [0,40,60,90],
            'ncı' => [6],
            'uncu' => [9,10,30]
        ];

        if(strlen($number) < 4) {
            if ($number % 10 == 0) {
                $numberKey = $number;
            } else $numberKey = substr($number, -1,1);
        }

        foreach ($numberValue as $orderKey => $numbers) {
            if (array_search($numberKey, $numbers) !== false) {
                $returnString = $orderKey;
            }
        }

        return $returnString;

    }

    public static function now ( array $param = [] )
    {
        return date("Y-m-d H:i:s");
    }

    public static function todayDate ( array $param = [] )
    {
        return date("Y-m-d");
    }

    public static function moneyFormatWithTwoDecimals($money)
    {
        $money = str_replace(",","",$money);
        return number_format($money,2,'.','');
    }

    public static function getXmlResponse ($view,$data)
    {
        $responseObj = App::make("Response");
        return $responseObj::view($view,$data)->header('Content-Type', 'text/xml');
    }

    public static function preDie($args)
    {

            echo '<pre>';
            print_r($args);
            echo '</pre>';

        die;
    }
}
