<?php

declare(strict_types=1);

namespace Meibuyu\Micro\Model;

use Hyperf\DbConnection\Model\Model ;

abstract class BaseModel extends Model
{


    /**
     * Function addDataToMysql
     * 批量插入数据到数据库,无则插入,重复则更新
     */

    public function batchUpdateOrCreateByUniqueKey($data)
    {
        $buildInsertBatchSqlStr = $this->buildInsertBatchSqlStr($data);
        $sql = $buildInsertBatchSqlStr['sql'];
        return $this->getConnection()->update($sql);

    }

    /**
     * Function buildInsertBatchSqlStr
     * 组装mysql
     */

    private function buildInsertBatchSqlStr($data)
    {
        //从data中 获取更新的字段
        if (empty($data)) {
            return false;
        }
        $new_data=[];
        $maxdim=$this->getmaxdim($data);

        if($maxdim==1){
            // 兼容一维数组
            $new_data[]=$data;
        }elseif($maxdim>2){
            // 大于2维返回false
            return false;
        }else{
            $new_data=$data;
        }
        $keys_arr = [];
        $datas_arr = [];
        $where_arr = [];
        foreach ($new_data as $k => $v) {
            if (!$keys_arr) {
                $keys_arr = array_keys($v);
            }
            foreach ($v as $k2=>&$v2){
                if(is_string($v2)){
                    $v2="'".addslashes($v2)."'";
                }
            }
            //数据重组
            $onedata = "( " . implode(',', $v) . " )";
            $datas_arr[] = $onedata;
            unset($onedata);

        }
        // 组装格式 pt_uid=VALUES(pt_uid),
        foreach ($keys_arr as $k2 => $v2) {
            $where_arr[] = "$v2 = VALUES($v2)";

        }
        $keys_str = implode(',', $keys_arr);
        $datas_str = implode(',', $datas_arr);
        $where_str = implode(',', $where_arr);
        $sql = "";
        if ($keys_str && $datas_str && $where_str) {
            $table = $this->getTable();
            $sql = " INSERT INTO $table ( $keys_str ) VALUES $datas_str ON DUPLICATE KEY UPDATE $where_str";
        }
        unset($keys_str, $where_str);
        return ['sql' => $sql, 'count' => count($datas_arr)];
    }


    /**
     * Function getmaxdim
     * 数组维数
     */
    private  function getmaxdim($vDim){
        if(!is_array($vDim)) return 0;
        else {
            $max1 = 0;
            foreach($vDim as $item1) {
                $t1 = $this->getmaxdim($item1);
                if( $t1 > $max1) $max1 = $t1;
            }
            return $max1 + 1;
        }
    }


    /**
     * 批量更新数组 有则
     * @param $data array 待更新的数据,二维数组格式
     * @param string $field string 值不同的条件,默认为id
     * @return bool|string
     */
    public function batchUpdateByField($data, $field = null)
    {
        if(is_null($field))    $field = $this->getKeyName();

        if (!is_array($data) || !$field ) {
            return false;
        }

        $updates = $this->parseUpdate($data, $field);

        // 获取所有键名为$field列的值,值两边加上单引号,保存在$fields数组中
        // array_column()函数需要PHP5.5.0+,如果小于这个版本,可以自己实现,
        // 参考地址:http://php.net/manual/zh/function.array-column.php#118831
        $fields = array_column($data, $field);
        $fields = implode(',', array_map(function($value) {
            return "'".$value."'";
        }, $fields));

        $sql = sprintf(
            "UPDATE `%s` SET %s WHERE `%s` IN (%s) ",
            $this->getTable(), $updates, $field, $fields
        );

        return $this->getConnection()->update($sql);
    }

    /**
     * 将二维数组转换成CASE WHEN THEN的批量更新条件
     * @param $data array 二维数组
     * @param $field string 列名
     * @return string sql语句
     */
    private  function parseUpdate($data, $field)
    {
        $sql = '';
        $keys = array_keys(current($data));
        foreach ($keys as $column) {
            if($column==$keys) continue;
            $sql .= sprintf("`%s` = CASE `%s` \n", $column, $field);
            foreach ($data as $line) {
                $sql .= sprintf(
                    "WHEN '%s' THEN '%s' \n",
                    $line[$field],
                    !is_numeric($line[$column])?addslashes($line[$column]):$line[$column],
                );
            }
            $sql .= "END,";
        }

        return rtrim($sql, ',');
    }

}