<?php namespace Pay\Src;

use Dever;

class Api
{
	/**
	 * 发起跳转
	 *
	 * @return mixed
	 */
	public function jump()
	{
		$url = Dever::input('refer');
		$url = urldecode($url);
		Dever::location($url);
	}

	# 获取支付渠道
	public function channel()
	{
		$data = Dever::db('pay/channel')->getData();
		return $data;
	}

	/**
	 * 发起支付 下单 获取预支付信息
	 *
	 * @return mixed
	 */
	public function get($type = 1, $param = array())
	{
		if (!$type) {
			$type = 1;
		}
		$this->init($param);
		if ($this->order_id) {
			$pay = Dever::db('pay/order')->one(array('order_id' => $this->order_id));
			if ($pay && $pay['status'] == 1 && $pay['param']) {
				$order = Dever::array_decode($pay['param']);
				if (isset($order['payMsg']) && $order['payMsg']) {
					return $order['payMsg'];
				}
				return $order;
			}
		}
		return $this->method->order($this->account_id, $this->project_id, $this->uid, $this->username, $this->product_id, $this->name, $this->cash, $this->openid, $type, $this->order_id, $this->other, $this->refer);
	}

	/**
	 * notify
	 *
	 * @return mixed
	 */
	public function notify($param = array())
	{
		$this->checkAccount($param);
		$this->handle();
		return $this->method->notify();
	}

	/**
	 * 发起支付 通用的发起支付方法
	 *
	 * @return mixed
	 */
	public function pay($param = array())
	{
		$system_source = $this->getParam($param, 'system_source');
		$receipt = $this->getParam($param, 'receipt');
		$account_id = $this->getParam($param, 'account_id');

		$config = Dever::config('base', 'pay')->pay['method'];

		if (isset($config[$system_source])) {
			$param['account_id'] = $account_id ? $account_id : $system_source;
			$method = $config[$system_source];
			if ($system_source == 3 && $receipt) {
				$method = $method[1];
				$param['other'] = $receipt;
			}
			$result = array();
			$result['order'] = $this->$method($param);
			$result['order_id'] = $this->method->order_id;
			$result['type'] = $this->type;

			return $result;
		} else {
			Dever::alert('错误的source');
		}
	}

	/**
	 * 发起支付 用于小程序支付
	 *
	 * @return mixed
	 */
	public function applet($param = array())
	{
		$param['system_source'] = 4;
		$this->init($param);
		return $this->method->applet($this->get(1));
	}

	/**
	 * 发起支付 用于app支付
	 *
	 * @return mixed
	 */
	public function app($param = array())
	{
		$param['system_source'] = 1;
		$this->init($param);
		$this->openid = -1;
		return $this->method->app($this->get(3));
	}

	/**
	 * 发起支付 用于苹果内购支付
	 *
	 * @return mixed
	 */
	public function apple($param = array())
	{
		$this->init($param);
		# 只需验证苹果过来的参数即可
		return Dever::load('pay/lib/apple')->check($this->other, $this->account_id, $this->project_id, $this->uid, $this->username, $this->product_id, $this->name, $this->cash, $this->order_id);
	}

	/**
	 * 发起支付 用于页面支付
	 *
	 * @return mixed
	 */
	public function page($param = array())
	{
		$this->init($param);
		if (!$this->refer && $this->type != 'test') {
			Dever::alert('没有回调refer');
		}
		$type = 1;
		if ($this->h5 == 1) {
			$type = 4;
		}
		return $this->method->page($this->get($type), $this->refer);
	}

	/**
	 * 发起支付 用于扫码支付
	 *
	 * @return mixed
	 */
	public function qrcode($param = array())
	{
		$this->init($param);
		return $this->method->qrcode($this->get(2), $this->refer);
		Dever::apply('sdk/qrcode');
		return \QRcode::png($url);
	}

	/**
	 * 查询支付
	 *
	 * @return mixed
	 */
	public function search($param = array())
	{
		$this->checkAccount($param);
		$this->handle();
		$this->order_id = $this->getParam($param, 'order_id');
		return $this->method->search($this->order_id);
	}

	/**
	 * 退款
	 *
	 * @return mixed
	 */
	public function refund($param = array())
	{
		$this->checkAccount($param);
		$this->handle();
		$this->other = $this->getParam($param, 'other');
		$this->order_id = $this->getParam($param, 'order_id');
		$this->refund_order_id = $this->getParam($param, 'refund_order_id');
		$this->refund_cash = $this->getParam($param, 'refund_cash');
		return $this->method->refundByOrder($this->order_id, $this->refund_order_id, $this->refund_cash, $this->other);
	}

	/**
	 * 初始化 设置参数
	 *
	 * @return mixed
	 */
	private function init($param = array())
	{
		if (isset($this->account_id)) {
			return;
		}
		$this->checkAccount($param);
		$this->project_id = $this->getParam($param, 'project_id');
		$this->uid = $this->getParam($param, 'uid');
		$this->openid = $this->getParam($param, 'openid');
		$this->username = $this->getParam($param, 'username');
		$this->product_id = $this->getParam($param, 'product_id');
		$this->name = $this->getParam($param, 'name');
		$this->cash = $this->getParam($param, 'cash');
		$this->refer = $this->getParam($param, 'refer');
		$this->order_id = $this->getParam($param, 'order_id');
		$this->other = $this->getParam($param, 'other');
		$this->h5 = $this->getParam($param, 'h5');
		$this->ip = $this->getParam($param, 'ip');

		if (!$this->project_id) {
			$this->project_id = false;
		}

		if (!$this->order_id) {
			$this->order_id = false;
		}

		if (!$this->uid) {
			Dever::alert('没有用户信息');
		}

		if (!$this->product_id) {
			Dever::alert('没有产品信息');
		}

		if (!$this->name) {
			Dever::alert('没有支付信息');
		}

		if (!$this->cash) {
			Dever::alert('没有支付金额');
		}

		if (!$this->ip) {
			$this->ip = Dever::ip();
		}

		return $this->handle();
	}

	/**
	 * 初始化 验证账户信息
	 *
	 * @return mixed
	 */
	private function checkAccount($param = array())
	{
		$this->channel_id = $this->getParam($param, 'channel_id');
		$this->system_source = $this->getParam($param, 'system_source');
		$this->account_id = $this->getParam($param, 'account_id');

		if (!$this->account_id && !$this->channel_id && !$this->system_source) {
			Dever::alert('没有账户信息');
		}
	}

	/**
	 * 初始化
	 *
	 * @return mixed
	 */
	private function getParam($param, $key)
	{
		if (isset($param[$key])) {
			return $param[$key];
		}
		return Dever::input($key, false);
	}

	/**
	 * 获取支付类
	 *
	 * @return mixed
	 */
	private function handle()
	{
		$pay = false;
		if ($this->account_id > 0) {
			$pay = Dever::db('pay/account')->one($this->account_id);
		} elseif ($this->channel_id && $this->system_source) {
			$pay = Dever::db('pay/account')->one(array('channel_id' => $this->channel_id, 'system_source' => $this->system_source));
		}

		if (!$pay || ($pay && $pay['state'] != 1)) {
			Dever::alert('没有账户信息');
		}
		
		if (!$pay['type']) {
			Dever::alert('账户类型错误');
		}

		$this->account_id = $pay['id'];
		/*
		$this->channel_id = $pay['channel_id'];
		$this->system_source = $pay['system_source'];
		*/
		if ($pay['box'] == 3) {
			$pay['type'] = 'test';
		}

		$this->type = $pay['type'];

		$method = '\\Pay\\Lib\\' . ucwords($pay['type']);
		if (isset($this->refer) && $this->refer) {
			$pay['refer'] = $this->refer;
		}
		if (isset($this->ip) && $this->ip) {
			$pay['ip'] = $this->ip;
		}
		
		$this->method = new $method($pay);
		return $this;
	}
}
