<?php namespace Api\Lib\Platform;
use Dever;
class Value
{
    protected static $load;
    public static function load($field)
    {
        if (empty(self::$load)) {
            self::$load = new self($field);
        }
        return self::$load;
    }

    public function __construct($field)
    {
        $this->field = $field;
    }

    public function get($config, $data)
    {
        $result = array();
        if ($config) {
            foreach ($data as $k => $v) {
                $this->field->set($k, $v);
            }
            $source = array();
            $dest = array();
            foreach ($config as $k => $v) {
                $temp = $this->convert($data, $v['value'], $v['key'], $v['type']);
                if ($temp) {
                    $result = array_replace_recursive($result, $temp);
                }
            }
        }
        if ($result) {
            $result = $this->value($result);
        } else {
            $result = $data;
        }
        return $result;
    }

    public function convert($array, $source, $dest, $type = '')
    {
        $source = explode('.', $source);
        $dest = explode('.', $dest);
        $extracted = $this->extracted($array, $source, $type);
        return $this->transform($extracted, $dest);
    }

    public function extracted(&$array, $source, $type = '')
    {
        $current = array_shift($source);
        if (substr($current, -2) == '[]') {
            $current = substr($current, 0, -2);
            $result = [];
            if (isset($array[$current]) && is_array($array[$current])) {
                foreach ($array[$current] as $item) {
                    $sub = $this->extracted($item, $source, $type);
                    if ($sub !== null) {
                        $result[] = $sub;
                    }
                }
            }
            return $result;
        } else {
            $result = '';
            if (isset($array[$current])) {
                if (empty($source)) {
                    $result = $array[$current];
                } else {
                    return $this->extracted($array[$current], $source, $type);
                }
            } elseif ($this->field->$current) {
                $result = $this->field->$current;
            } else {
                $result = $current;
            }
            if ($type) {
                $result .= '||' . $type;
            }
            return $result;
        }
        return null;
    }

    protected function transform($value, $dest)
    {
        $current = array_shift($dest);
        if (substr($current, -2) == '[]') {
            $current = substr($current, 0, -2);
            $result = [];
            $result[$current] = [];
            foreach ($value as $item) {
                $result[$current][] = $this->transform($item, $dest);
            }
            return $result;
        } else {
            if (empty($dest)) {
                return [$current => $value];
            } else {
                return [$current => $this->transform($value, $dest)];
            }
        }
    }

    protected function value($data)
    {
        if (!is_array($data)) {
            return $data;
        }
        foreach ($data as $k => $v) {
            if (!is_array($v)) {
                $temp = explode('||', $v);
                $this->field->set($k, $temp[0]);
            }
        }
        foreach ($data as $k => $v) {
            if (is_array($v)) {
                if (isset($v[0])) {
                    foreach ($v as $k1 => $v1) {
                        $data[$k][$k1] = $this->value($v1);
                    }
                } else {
                    $data[$k] = $this->value($v, $key);
                }
            } else {
                $temp = explode('||', $v);
                if (empty($temp[1])) {
                    $temp[1] = '';
                }
                $data[$k] = $this->field->value($temp[0], $temp[1], false);
                $this->field->set($k, $data[$k]);
            }
        }
        return $data;
    }
}