<?php

/**
 * Class Owner
 */
class Owner extends MY_Model
{
    const TABLE_OWNER_SELL = 'owner_sell';
    const TABLE_OWNER_RENT = 'owner_rent';
    const INTERFACE_CHECK_OWNER = 'http://openapi.njhouse.com.cn/house365/checkOwner';
    const INTERFACE_PUSH_RENT = 'http://openapi.njhouse.com.cn/import/rentFromPerson';
    const INTERFACE_ACCOUNT = 'test';
    const INTERFACE_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5neCmLXlF9IR4RALGC9diS2Yd
9eyY5ZVnm1L4aDDayF6BX+uXAh9bs5gBM+99FMTVgJdvxotmdToxw0sy+OK/MW3P
9c8GV1UieLvmwodcNNFs38hEa88NyJDzpmHaXVpwEj0XRJK6tdxRw/Gmy+SsLu/9
UqsiyiRKICb0UDZ8KQIDAQAB
-----END PUBLIC KEY-----';

    /**
     * Get Insert SQL
     * @param string $table
     * @param array $data
     * @return string
     */
    private function getInsertSQL($table = '', $data = array())
    {
        $table = is_string($table) ? $table : '';
        $data = is_array($data) ? $data : array();
        $insertKey = array();
        $insertValue = array();
        foreach ($data as $key => $value) {
            array_push($insertKey, sprintf('`%s`', $key));
            array_push($insertValue, sprintf('"%s"', $value));
        }
        $insertKeyString = implode(',', $insertKey);
        $insertValueString = implode(',', $insertValue);
        $sql = sprintf('INSERT INTO `%s` (%s) VALUES (%s)', $table, $insertKeyString, $insertValueString);
        return $sql;
    }

    /**
     * Get Replace SQL
     * @param string $table
     * @param array $data
     * @return string
     */
    private function getReplaceSQL($table = '', $data = array())
    {
        $table = is_string($table) ? $table : '';
        $data = is_array($data) ? $data : array();
        $insertKey = array();
        $insertValue = array();
        foreach ($data as $key => $value) {
            array_push($insertKey, sprintf('`%s`', $key));
            array_push($insertValue, sprintf('"%s"', $value));
        }
        $insertKeyString = implode(',', $insertKey);
        $insertValueString = implode(',', $insertValue);
        $sql = sprintf('REPLACE INTO `%s` (%s) VALUES (%s)', $table, $insertKeyString, $insertValueString);
        return $sql;
    }

    /**
     * CURL Post
     * @param string $url
     * @param array $post
     * @return string
     */
    private function curlPost($url = '', $post = array())
    {
        $option = array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => false,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $post,
            CURLOPT_TIMEOUT => 2
        );
        $curl = curl_init($url);
        curl_setopt_array($curl, $option);
        $result = curl_exec($curl);
        curl_close($curl);
        return is_string($result) ? $result : '';
    }

    /**
     * Interface Encoding
     * @param string $string
     * @return null|string|string[]
     */
    private function interfaceEncoding($string = '')
    {
        return mb_convert_encoding($string, 'UTF-8', 'GBK');
    }

    /**
     * Interface Encrypt Data
     * @param array $data
     * @return string
     */
    private function interfaceEncryptData($data = array())
    {
        // To JSON
        $dataJSON = json_encode($data);
        // To Encrypt
        $publicKeyID = openssl_pkey_get_public(self::INTERFACE_PUBLIC_KEY);
        $dataEncrypt = '';
        foreach (str_split($dataJSON, 117) as $chunk) {
            openssl_public_encrypt($chunk, $dataEncryptChunk, $publicKeyID);
            $dataEncrypt .= $dataEncryptChunk;
        }
        // To Base64
        $dataBase64 = base64_encode($dataEncrypt);
        // To URLEncode
        $dataURLEncode = urlencode($dataBase64);
        return $dataURLEncode;
    }

    /**
     * Interface Submit
     * @param string $url
     * @param array $data
     * @return array|mixed
     */
    private function interfaceSubmit($url = '', $data = array())
    {
        $encryptData = $this->interfaceEncryptData($data);
        $result = $this->curlPost($url, array(
            'account' => self::INTERFACE_ACCOUNT,
            'data' => $encryptData
        ));
        return json_decode($result, true);
    }

    /**
     * Interface Check Owner
     * @param array $data
     * @return bool
     */
    private function interfaceCheckOwner($data = array())
    {
        $submitData = array(
            'ywbh' => time(), // 业务编号
            'h' => array( // 户
                array(
                    'qqh' => $data['land_right_number'], // 丘权号
                    'fwdm' => '', // 房屋代码  空，备用
                    'zl' => $this->interfaceEncoding($data['district']), // 坐落
                    'jzmj' => $data['area'] // 建筑面积
                )
            ),
            'qlr' => array( // 权利人
                array(
                    'mc' => $this->interfaceEncoding($data['name']), // 名称
                    'zjlb' => $this->interfaceEncoding('居民身份证'), // 证件类别
                    'zjhm' => $data['identity_card_number'], // 证件号码
                    'qszslx' => $data['contract_type'], // 权属证书类型 0-房屋所有权证 1-不动产权证书 2-商品房预（现）售合同
                    'qszshm' => $this->interfaceEncoding($data['contract_number']) // 权属证书号码
                )
            )
        );
        $result = $this->interfaceSubmit(self::INTERFACE_CHECK_OWNER, $submitData);
        if (isset($result['status']) && intval($result['status']) == 1) {
            return true;
        }
        return false;
    }

    /**
     * Owner constructor.
     */
    public function __construct()
    {
        parent::__construct(1, 1, 0);
    }

    /**
     * Get Contract Type
     * @return array
     */
    public function getContractType()
    {
        return array(
            '0' => '房屋所有权证',
            '1' => '不动产权证书',
            '2' => '商品房预（现）售合同'
        );
    }

    /**
     * Get Sell Information
     * @param int $houseID
     * @return array|null
     */
    public function getSellInformation($houseID = 0)
    {
        $result = $this->db
            ->where('house_id', $houseID)
            ->select('*')
            ->get(self::TABLE_OWNER_SELL);
        if ($result) {
            $result = $result->result_array();
        }
        return isset($result[0]) && is_array($result[0]) ? $result[0] : null;
    }

    /**
     * Get Rent Information
     * @param int $houseID
     * @return array|null
     */
    public function getRentInformation($houseID = 0)
    {
        $result = $this->db
            ->where('house_id', $houseID)
            ->select('*')
            ->get(self::TABLE_OWNER_RENT);
        if ($result) {
            $result = $result->result_array();
        }
        return isset($result[0]) && is_array($result[0]) ? $result[0] : null;
    }

    /**
     * Update Sell
     * @param array $data
     * @param bool $isCeckOwner
     * @return bool
     */
    public function updateSell($data = array(), $isCeckOwner = false)
    {
        if (empty($data['house']['id'])) {
            return false;
        }
        $updateData = array();
        $updateField = array(
            'house_id',
            'land_right_number',
            'contract_number',
            'contract_type',
            'name',
            'phone',
            'identity_card_number',
            'update_time',
            'owner_real'
        );
        $resultData = $this->getSellInformation($data['house']['id']);
        if (isset($resultData)) {
            foreach ($resultData as $keys => $values) {
                if (!is_numeric($keys)) {
                    if (!in_array($keys, $updateField)) {
                        array_push($updateField, $keys);
                    }
                }
            }
        }
        foreach ($updateField as $field) {
            $updateData[$field] = isset($resultData[$field]) ? $resultData[$field] : '';
            $updateData[$field] = isset($data[$field]) ? $data[$field] : $updateData[$field];
        }
        $updateData['house_id'] = $data['house']['id'];
        $updateData['update_time'] = time();
        if ($isCeckOwner) {
            if (!empty($data['name']) && !empty($data['land_right_number'])) {
                $isOwnerReal = $this->interfaceCheckOwner(array(
                    'district' => $data['house']['district'],
                    'area' => $data['house']['area'],
                    'name' => $updateData['name'],
                    'identity_card_number' => $updateData['identity_card_number'],
                    'land_right_number' => $updateData['land_right_number'],
                    'contract_type' => $updateData['contract_type'],
                    'contract_number' => $updateData['contract_number']
                ));
                $updateData['owner_real'] = $isOwnerReal ? 1 : 2;
            }
        }
        $updateSQL = $this->getReplaceSQL(self::TABLE_OWNER_SELL, $updateData);
        $this->db->query($updateSQL);
        return true;
    }

    /**
     * Update Rent
     * @param array $data
     * @param bool $isCeckOwner
     * @return bool
     */
    public function updateRent($data = array(), $isCeckOwner = false)
    {
        if (empty($data['house']['id'])) {
            return false;
        }
        $updateData = array();
        $updateField = array(
            'house_id',
            'land_right_number',
            'contract_number',
            'contract_type',
            'name',
            'phone',
            'identity_card_number',
            'update_time',
            'owner_real'
        );
        $resultData = $resultData = $this->getRentInformation($data['house']['id']);
        if (isset($resultData)) {
            foreach ($resultData as $keys => $values) {
                if (!is_numeric($keys)) {
                    if (!in_array($keys, $updateField)) {
                        array_push($updateField, $keys);
                    }
                }
            }
        }
        foreach ($updateField as $field) {
            $updateData[$field] = isset($resultData[$field]) ? $resultData[$field] : '';
            $updateData[$field] = isset($data[$field]) ? $data[$field] : $updateData[$field];
        }
        $updateData['house_id'] = $data['house']['id'];
        $updateData['update_time'] = time();
        if ($isCeckOwner) {
            if (!empty($data['name']) && !empty($data['land_right_number'])) {
                $isOwnerReal = $this->interfaceCheckOwner(array(
                    'district' => $data['house']['district'],
                    'area' => $data['house']['area'],
                    'name' => $updateData['name'],
                    'identity_card_number' => $updateData['identity_card_number'],
                    'land_right_number' => $updateData['land_right_number'],
                    'contract_type' => $updateData['contract_type'],
                    'contract_number' => $updateData['contract_number']
                ));
                $updateData['owner_real'] = $isOwnerReal ? 1 : 2;
            }
        }
        $updateSQL = $this->getReplaceSQL(self::TABLE_OWNER_RENT, $updateData);
        $this->db->query($updateSQL);
        return true;
    }
}
