<?php

namespace Helpers\Outil;

use DateTime;
use Error;
use Helpers\Log\LogSysteme;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Helpers\Outil\Sql;

class Date
{
    
    public function __construct()
    {
    }
    
    /**
     * From format "Ymd" to "displayed" format
     * return le format date en fonction du DATE_FORMAT
     * @param string $date Ymd
     * @return string
     */
    public static function dateConverte($date, ?string $format = null)
    {
        if (empty($date) || $date == '00000000') {
            return '';
        }

        $year = substr($date, 0, 4);
        $month = substr($date, 4, 2);
        $day = substr($date, 6, 2);


        switch ($format ?? $_SESSION['DATE_FORMAT']) {
            case 'aaaa/mm/jj':
                return $year.'/'.$month.'/'.$day;
            case 'mm/jj/aaaa':
                return $month.'/'.$day.'/'.$year;
            case 'aa-mm-jj':
                return substr($year, 2, 2).'-'. $month.'-'.$day;
            case 'aaaa-mm-jj':
                return $year.'-'. $month.'-'.$day;
            case 'jj/mm/aaaa':
                return $day.'/'. $month.'/'.$year;
            default:
        }
        return $day.'/'. $month.'/'.$year;
    }

    public static function getDefaultFormat() :string
    {
        switch ($_SESSION['DATE_FORMAT']) {
            case 'aaaa/mm/jj':
                return 'Y/m/d';
            case 'mm/jj/aaaa':
                return 'm/d/Y';
            case 'aa-mm-jj':
                return 'y-m-d';
            case 'aaaa-mm-jj':
                return 'Y-m-d';
            case 'jj/mm/aaaa':
            default:
                return 'd/m/Y';
        }
    }
    
    /**
     * From format "HHMMSS" to "displayed" format
     * return une heure formatée
     * @param string $date HHMMSS
     * @return string
     */
    public static function heureConverte($date)
    {
        if (empty($date) || $date == '000000') {
            return '';
        }

        if (strlen($date) > 6) {
            return $date;
        }

        $hours = substr($date, 0, 2);
        $minutes = substr($date, 2, 2);
        $seconds = substr($date, 4, 2);

        return $hours . ':' . $minutes . ':' . $seconds;
    }

    /**
     * return date pour BDD YYYYMMDD
     * @param string $date
     * @param string $dateMin
     * @param string $dateMax
     * @param bool $oxadw
    */
    public static function dateToSql(&$date, $dateMin = '', $dateMax = '', $oxadw = false, ?string $format = null) : bool
    {
        $date = str_replace('/', '', $date);
        $date = str_replace('-', '', $date);
        
    
        if ('aaaa/mm/jj' == ($format??$_SESSION['DATE_FORMAT'])) { // format : aaaa/mm/jj
            $moisBDD = $mois = mb_substr($date, 4, 2);
            $jour = mb_substr($date, 6, 2);
            $annee = (int)mb_substr($date, 0, 4);
            
            if ('0' == mb_substr($mois, 0, 1)) {
                $mois = mb_substr($mois, 1, 2);
            }
            if (!checkdate((int)$mois, (int)mb_substr($date, 6, 2), (int)mb_substr($date, 0, 4)) || '00000000' == $date) {
                 return false;
            } else {
                if ($oxadw) {
                    $date = "$annee-$moisBDD-$jour 00:00:00.000";
                } else {
                    $date = $annee.$moisBDD.$jour;
                }
                return true;
            }
        } elseif ('mm/jj/aaaa' == ($format??$_SESSION['DATE_FORMAT'])) {  // format : mm/jj/aaaa
            $annee = mb_substr($date, 4, 4);
            if (mb_strlen($annee) == 2) {
                $annee = '20'.$annee;
            }
            
            if (mb_strlen($annee) == 4) {
                $moisBDD = $mois = mb_substr($date, 0, 2);
                $jour = mb_substr($date, 2, 2);
                $annee = (int)mb_substr($date, 4, 4);
                
                if ('0' == mb_substr($mois, 0, 1)) {
                    $mois = mb_substr($mois, 1, 2);
                }
                
                if (!checkdate((int)$mois, (int)mb_substr($date, 2, 2), (int)mb_substr($date, 4, 4)) || '00000000' == $date) {
                     return false;
                } else {
                    if ($oxadw) {
                        $date = "$annee-$moisBDD-$jour 00:00:00.000";
                    } else {
                        $date = $annee.$moisBDD.$jour;
                    }
                    return true;
                }
            } else {
                return false;
            }
        } elseif ('aa-mm-jj' == ($format??$_SESSION['DATE_FORMAT'])) {  // format : aa-mm-jj
            $moisBDD = $mois = mb_substr($date, 2, 2);
            if ('0' == mb_substr($mois, 0, 1)) {
                $mois = mb_substr($mois, 1, 2);
            }
            
            $jour = substr($date, 4, 2);
            $annee = '20'.(int)mb_substr($date, 0, 2);
            
            if (!checkdate((int)$mois, (int)substr($date, 4, 2), intval('20'.mb_substr($date, 0, 2))) || '00000000' == $date) {
                return false;
            } else {
                if ($oxadw) {
                    $date = "$annee-$moisBDD-$jour 00:00:00.000";
                } else {
                    $date = $annee.$moisBDD.$jour;
                }
                return true;
            }
        } elseif ('aaaa-mm-jj' == ($format??$_SESSION['DATE_FORMAT'])) {  // format : aaaa-mm-jj
            $moisBDD = $mois = mb_substr($date, 4, 2);
            if ('0' == mb_substr($mois, 0, 1)) {
                $mois = mb_substr($mois, 1, 2);
            }
            
            $jour = mb_substr($date, 6, 2);
            $annee = (int)mb_substr($date, 0, 4);
            
            if (!checkdate((int)$mois, (int)mb_substr($date, 6, 2), (int)mb_substr($date, 0, 4)) || '00000000' == $date) {
                return false;
            } else {
                if ($oxadw) {
                    $date = "$annee-$moisBDD-$jour 00:00:00.000";
                } else {
                    $date = $annee.$moisBDD.$jour;
                }
                return true;
            }
        } elseif (array_key_exists('Session_Login', $_SESSION) == false) {
            $annee = mb_substr($date, 4, 4);
            if (mb_strlen($annee) == 2) {
                $annee = '20'.$annee;
            }
            

   
            if (mb_strlen($annee) == 4) {
                $moisBDD = $mois = mb_substr($date, 2, 2);

                if ('0' == mb_substr($mois, 0, 1)) {
                    $mois = mb_substr($mois, 1, 2);
                }
                $jour = mb_substr($date, 0, 2);
                $annee = (int)mb_substr($date, 4, 4);
                
             
                if (!checkdate((int)$mois, (int)mb_substr($date, 0, 2), (int)mb_substr($date, 4, 4)) || '00000000' == $date) {
                    return false;
                } else {
                    if ($oxadw) {
                        $date = "$annee-$moisBDD-$jour 00:00:00.000";
                    } else {
                        $date = $annee.$moisBDD.$jour;
                    }
                    return true;
                }
            } else {
                return false;
            }
        } elseif ('jj/mm/aaaa' == ($format??$_SESSION['DATE_FORMAT'])) { // format : jj/mm/aaaa
            $annee = mb_substr($date, 4, 4);
            if (mb_strlen($annee) == 2) {
                $annee = '20'.$annee;
            }
            
            if (mb_strlen($annee) == 4) {
                $moisBDD = $mois = mb_substr($date, 2, 2);
                if ('0' == mb_substr($mois, 0, 1)) {
                    $mois = mb_substr($mois, 1, 2);
                }
                
                $jour = mb_substr($date, 0, 2);
                $annee = (int)mb_substr($date, 4, 4);
                
                if (!checkdate((int)$mois, (int)mb_substr($date, 0, 2), (int)mb_substr($date, 4, 4)) || '00000000' == $date) {
                    return false;
                } else {
                    if ($oxadw) {
                        $date = "$annee-$moisBDD-$jour 00:00:00.000";
                    } else {
                        $date = $annee.$moisBDD.$jour;
                    }
                    return true;
                }
            } else {
                return false;
            }
        } else {
             return false;
        }
    }
    
    /**
     * Fonction permetant de convertir le mois
     * utilisé sans les historiques
     * @param string $date
     * @return string
     * NOTE BBA : Changer pour mettre traduction multiple
     */
    public static function convertDateEnMois($date, ITrad $trad)
    {
        $mois = substr($date, 4, 2);
        
        switch ($mois) {
            case '01':
                return  $trad->t('Janvier');
            case '02':
                return $trad->t('Février');
            case '03':
                return $trad->t('Mars');
            case '04':
                return $trad->t('Avril');
            case '05':
                return $trad->t('Mai');
            case '06':
                return $trad->t('Juin');
            case '07':
                return $trad->t('Juillet');
            case '08':
                return $trad->t('Août');
            case '09':
                return $trad->t('Septembre');
            case '10':
                return $trad->t('Octobre');
            case '11':
                return $trad->t('Novembre');
            case '12':
                return $trad->t('Décembre');
        }
        LogSysteme::prefixErrorLog((new \Exception('Invalid month "'.$mois.'"'))->__toString());
        return '';
    }
    
    /**
     * retourne le format neccesaire ne fonction du codeformat de la bdd.
     * @param string $num_format
     * @return string
     */
    public static function getDateFormatByNumDate($num_format)
    {
        switch ($num_format) {
            case '1':
                return 'jj/mm/aaaa';
            case '2':
                return 'mm/jj/aaaa';
            case '4':
                return 'aa-mm-jj';
            case '3':
                return 'aaaa-mm-jj';
        }
        
        return 'jj/mm/aaaa';
    }

    /**
     * getDebutMois
     *
     * @param string $date
     * @return int
     */
    public static function getDebutMois($date): int
    {
        $year=substr($date, 0, 4);
        $month=substr($date, 4, 2);

        return (int)($year.$month.'01');
    }

    /**
     * @param string $date
     */
    public static function getFinMois($date) : string
    {
        $year=substr($date, 0, 4);
        $month=substr($date, 4, 2);
        $day = cal_days_in_month(CAL_GREGORIAN, (int)$month, (int)$year);
        $day = sprintf('%02s', $day);

        return (string) $year.$month.$day;
    }

    /**
     * @param string $date
     */
    public static function getDayMois($date) : string
    {
        $day=substr($date, 6, 2);

        return (string)$day;
    }

    public static function getSameDayNextMonth(string $date, int $numberOfMonthsToAdd = 1) : string
    {
        $startDateYear=(int)substr($date, 0, 4);
        $startDateMonth=(int)substr($date, 4, 2);
        $startDateDay=(int)substr($date, 6, 2);
    
        $numberOfYearsToAdd = floor(($startDateMonth + $numberOfMonthsToAdd) / 12);
        if ((($startDateMonth + $numberOfMonthsToAdd) % 12) === 0) {
            $numberOfYearsToAdd--;
        }
        $year = $startDateYear + $numberOfYearsToAdd;
    
        $month = ($startDateMonth + $numberOfMonthsToAdd) % 12;
        if ($month === 0) {
            $month = 12;
        }
        $month = sprintf('%02s', $month);
    
        $numberOfDaysInMonth = (new DateTime("$year-$month-01"))->format('t');
        
        $day = $startDateDay;
        if ($startDateDay > $numberOfDaysInMonth) {
            $day = $numberOfDaysInMonth;
        }
        $day = sprintf('%02s', $day);
        
        return (string)$year.$month.$day;
    }

    /**
     * Date excel sont en "jours" tandis que linux en seconde
     * Date excel commence à partir de 1900 contre 1970 pour Linux
     * Supprimer 70 ans (25569) et multiplier par le nombre de seconde sur 1 jour (86400)
     * @param string $date
     * @param string $format
     * @return false|mixed|string|null
     */
    public static function transformExcelDateToPHP($date, string $format = 'd/m/Y')
    {
        $return = null;

        $d = DateTime::createFromFormat($format, $date);

        if ($d && $d->format($format) == $date) {
            $return = $date;
        } else {
            $newTs = (int)(((int)$date - 25569) * 86400);

            $return = \date('d/m/Y', $newTs);
        }

        return $return;
    }

    public static function convert(string $s, ?string $inputFormat, string $outputFormat) :string
    {
        $dateTime = ($inputFormat === null ?
            new DateTime($s) :
            \DateTime::createFromFormat($inputFormat, $s));
        
        if ($dateTime && $dateTime->getTimestamp() > 0 /* Case : 00/00/0000 */) {
            return $dateTime->format($outputFormat);
        } else {
            return '';
        }
    }

    public static function isSqlDateBetween(string $date, string $min, string $max) :bool
    {
        return ($min == '00000000' || $min <= $date)
            && ($max == '00000000' || $max >= $date);
    }

    public static function heureTrad(string $heuresend) : string
    {
        $heure=substr($heuresend, 0, 2);
        $minute=substr($heuresend, 2, 2);
        $seconde = strlen($heuresend) >= 6 ? substr($heuresend, 4, 2) : '';

        
        if (!$heure && !$minute) {
            return '';
        }
        
        if ($seconde !== '') {
            return $heure . ':' . $minute . ':' . $seconde;
        } else {
            return $heure . ':' . $minute;
        }
    }

    public static function formatDatetime(string $date, bool $withHour = true) :string
    {
        if (empty($date)) {
            return '';
        }
        try {
            return (new DateTime($date))->format(
                Date::getDefaultFormat()
                . ($withHour ? ' H:i:s' : '')
            );
        } catch (\Exception $e) {
            LogSysteme::prefixErrorLog('Failed formatDatetime ' . (string) $e->getMessage());
            return '';
        }
    }
}
