<?php

/**
 * Class MC4WP_Field_Formatter
 *
 * Formats values based on what the Mailchimp API expects or accepts for the given field types.
 */
class MC4WP_Field_Formatter
{
    /**
     * @param mixed $value
     * @param object $options
     * @return array
     */
    public function address($value, $options = null)
    {
        // auto-format if this is a string
        if (is_string($value)) {
            // addr1, addr2, city, state, zip, country
            $address_pieces = explode(',', $value);
            $address_pieces = array_filter($address_pieces);
            $address_pieces = array_values($address_pieces);

            // try to fill it.... this is a long shot
            $value = [
                'addr1' => $address_pieces[0],
                'city'  => isset($address_pieces[1]) ? $address_pieces[1] : '',
                'state' => isset($address_pieces[2]) ? $address_pieces[2] : '',
                'zip'   => isset($address_pieces[3]) ? $address_pieces[3] : '',
            ];

            if (! empty($address_pieces[4])) {
                $value['country'] = $address_pieces[4];
            }
        } elseif (is_array($value)) {
            // merge with array of empty defaults to allow skipping certain fields
            $default = array_fill_keys([ 'addr1', 'city', 'state', 'zip' ], '');
            $value   = array_merge($default, $value);
        }

        return $value;
    }

    /**
     * @param mixed $value
     * @param object $options
     * @return string
     */
    public function birthday($value, $options = null)
    {
        $format = is_object($options) && isset($options->date_format) ? $options->date_format : 'MM/DD';

        if (is_array($value)) {
            // allow for "day" and "month" fields
            if (isset($value['month']) && isset($value['day'])) {
                $value = $value['month'] . '/' . $value['day'];
            } else {
                // if other array, just join together
                $value = join('/', $value);
            }
        }

        $value = trim($value);
        if (empty($value)) {
            return $value;
        }

        // always use slashes as delimiter, so next part works
        $value = str_replace([ '.', '-' ], '/', $value);

        // if format = DD/MM  OR if first part is definitely a day value (>12), then flip order
        // this allows `strtotime` to understand `dd/mm` values
        $values = explode('/', $value);
        if ($format === 'DD/MM' || ( $values[0] > 12 && $values[0] <= 31 && isset($values[1]) && $values[1] <= 12 )) {
            $values = array_reverse($values);
            $value  = join('/', $values);
        }

        // Mailchimp expects a MM/DD format, regardless of their display preference
        $value = (string) gmdate('m/d', strtotime($value));
        return $value;
    }

    /**
     * @param mixed $value
     * @param object $options
     * @return string
     */
    public function date($value, $options = null)
    {
        if (is_array($value)) {
            // allow for "year", "month" and "day" keys
            if (isset($value['year']) && isset($value['month']) && isset($value['day'])) {
                $value = $value['year'] . '/' . $value['month'] . '/' . $value['day'];
            } else {
                // if other array, just join together
                $value = join('/', $value);
            }
        }

        $value = trim($value);
        if (empty($value)) {
            return $value;
        }

        // Mailchimp expects a Y-m-d format no matter the display preference
        return (string) gmdate('Y-m-d', strtotime($value));
    }

    /**
     * @param string $value
     * @param object $options
     * @return string
     */
    public function language($value, $options = null)
    {
        $value = trim($value);

        $exceptions = [
            'pt_PT',
            'es_ES',
            'fr_CA',
        ];

        if (! in_array($value, $exceptions, true)) {
            $value = substr($value, 0, 2);
        }

        return $value;
    }

    /**
     * @param mixed $value
     * @param object $options
     * @return bool
     */
    public function boolean($value, $options = null)
    {
        $falsey = [ 'false', '0' ];

        if (in_array($value, $falsey, true)) {
            return false;
        }

        // otherwise, just cast.
        return (bool) $value;
    }
}
