<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_View_Data_CountDown' ) ) {

    class Pricely_View_Data_CountDown {

        private static $instance;
        private $date_time;
        private $datetime_util;
        private $validation_util;

        public static function get_instance(): self {

            if ( !self::$instance ) {

                self::$instance = new self();
            }

            return self::$instance;
        }

        public function __construct() {

            $this->datetime_util = Pricely_DateTime_Util::get_instance();
            $this->validation_util = Pricely_Validation_Util::get_instance();
        }

        public function get_data( $countdown_args, $view_id ) {

            $date_time = $this->get_date_time( $countdown_args );

            if ( !$date_time ) {

                return false;
            }

            $countdown = array(
                'datetime' => $this->get_countdown( $date_time ),
                'display' => $this->get_display_countdown( $date_time, $countdown_args[ 'auto_hide_days' ] ),
                'auto_refresh' => $countdown_args[ 'auto_refresh' ][ $view_id ]
            );

            return $countdown;
        }

        private function get_countdown( $date_time ) {

            $date_time->setTimezone( new DateTimeZone( 'UTC' ) );

            return $date_time->format( 'Y-m-d H:i:s' ) . ' +0000';
        }

        private function get_display_countdown( $date_time, $auto_hide_days ) {

            $current_time = current_time( 'U', wp_timezone() );

            $total_seconds = $date_time->format( 'U' ) - $current_time;

            $display_countdown = $this->get_default_display( $total_seconds, $auto_hide_days );

            if ( $total_seconds >= DAY_IN_SECONDS ) {

                $display_countdown[ 'days' ] = ( string ) floor( $total_seconds / DAY_IN_SECONDS );

                $total_seconds = $total_seconds - ( $display_countdown[ 'days' ] * DAY_IN_SECONDS );
            }

            if ( $total_seconds >= HOUR_IN_SECONDS ) {

                $display_countdown[ 'hours' ] = ( string ) floor( $total_seconds / HOUR_IN_SECONDS );

                $total_seconds = $total_seconds - ( $display_countdown[ 'hours' ] * HOUR_IN_SECONDS );
            }

            if ( $total_seconds >= MINUTE_IN_SECONDS ) {

                $display_countdown[ 'minutes' ] = ( string ) floor( $total_seconds / MINUTE_IN_SECONDS );

                $total_seconds = $total_seconds - ( $display_countdown[ 'minutes' ] * MINUTE_IN_SECONDS );
            }

            $display_countdown[ 'seconds' ] = ( string ) $total_seconds;


            if ( isset( $display_countdown[ 'days' ] ) && strlen( $display_countdown[ 'days' ] ) == 1 ) {

                $display_countdown[ 'days' ] = '0' . $display_countdown[ 'days' ];
            }

            if ( strlen( $display_countdown[ 'hours' ] ) == 1 ) {

                $display_countdown[ 'hours' ] = '0' . $display_countdown[ 'hours' ];
            }

            if ( strlen( $display_countdown[ 'minutes' ] ) == 1 ) {

                $display_countdown[ 'minutes' ] = '0' . $display_countdown[ 'minutes' ];
            }

            if ( strlen( $display_countdown[ 'seconds' ] ) == 1 ) {

                $display_countdown[ 'seconds' ] = '0' . $display_countdown[ 'seconds' ];
            }

            return $display_countdown;
        }

        private function get_date_time( $countdown_args ) {

            $date_time = false;


            if ( 'custom' == $countdown_args[ 'source' ] ) {

                $date_time = $this->get_custom_date_time( $countdown_args );
            }

            return $date_time;
        }

        private function get_custom_date_time( $countdown_args ) {

            $key = $countdown_args[ 'id' ];

            if ( isset( $this->date_time[ $key ] ) ) {

                return $this->date_time[ $key ];
            }

            $date_time = false;

            switch ( $countdown_args[ 'custom_mode' ] ) {

                case 'date':

                    $date_time = $this->get_custom_dt_by_date( $countdown_args );

                    break;

                case 'to_date':

                    $date_time = $this->get_custom_dt_by_to_date( $countdown_args );

                    break;

                default:
                    break;
            }

            $this->date_time[ $key ] = $date_time;

            return $this->date_time[ $key ];
        }

        private function get_custom_dt_by_date( $countdown_args ) {

            if ( !isset( $countdown_args[ 'date' ] ) ) {

                return false;
            }

            $from_date = $countdown_args[ 'date' ] . ' 00:00:00';
            $to_date = $countdown_args[ 'date' ] . ' 23:59:59';

            $current_date_time = $this->datetime_util->get_current_date( true );

            $from_is_valid = $this->validation_util->validate_date( '>=', $current_date_time, $from_date, 'Y-m-d H:i:s', 'Y-m-d H:i:s' );
            $to_is_valid = $this->validation_util->validate_date( '<=', $current_date_time, $to_date, 'Y-m-d H:i:s', 'Y-m-d H:i:s' );

            if ( !($from_is_valid && $to_is_valid) ) {

                return false;
            }

            return new DateTime( $to_date, wp_timezone() );
        }

        private function get_custom_dt_by_to_date( $countdown_args ) {

            if ( !isset( $countdown_args[ 'to_date' ] ) ) {

                return false;
            }

            $to_date = $countdown_args[ 'to_date' ] . ' 23:59:59';

            $current_date_time = $this->datetime_util->get_current_date( true );

            $to_is_valid = $this->validation_util->validate_date( '<=', $current_date_time, $to_date, 'Y-m-d H:i:s', 'Y-m-d H:i:s' );

            if ( !$to_is_valid ) {

                return false;
            }

            return new DateTime( $to_date, wp_timezone() );
        }

        private function get_default_display( $total_seconds, $auto_hide_days ) {

            if ( $total_seconds < DAY_IN_SECONDS && $auto_hide_days ) {

                return array(
                    'hours' => '00',
                    'minutes' => '00',
                    'seconds' => '00',
                );
            }

            return array(
                'days' => '00',
                'hours' => '00',
                'minutes' => '00',
                'seconds' => '00',
            );
        }

    }

}