<?php

/**
 * iCMS - i Content Management System
 * Copyright (c) 2007-2017 iCMSdev.com. All rights reserved.
 *
 * @author icmsdev <master@icmsdev.com>
 * @site https://www.icmsdev.com
 * @licence https://www.icmsdev.com/LICENSE.html
 */
defined('iPHP') or exit('What are you doing?');

class UserApp
{
	public $openid = null;
	public $me     = array();

	public function __construct()
	{
		User::init();
		UserCP::forward();
		$this->subApp();
	}
	/**
	 * 子应用
	 *
	 * @return void
	 */
	public function subApp()
	{
		$do = iAPP::$DO;
		$subApp = sprintf("User%sApp", ucfirst($do));
		$path = iAPP::path('user',$subApp);
		if (@is_file($path)) {
			$this->instance = new $subApp;
		} elseif (in_array($do, UserPassportApp::$apiList)) {
			$this->instance = new UserPassportApp();
		}
	}

	public function home($name = 'index')
	{
		UserCP::user();
		$node = [];
		if ($cid = (int)Request::get('cid')) {
			$node = UserNodeModel::where(compact('cid', 'appid'))->get();
		}
		View::append('user', compact('node'), true);
		View::display('iCMS://user/home.' . $name . '.htm');
	}
	public function API_iCMS()
	{
		$this->home();
	}
	public function API_home()
	{
		$this->home();
	}

	public function API_fans()
	{
		$this->home('fans');
	}
	public function API_follower()
	{
		$this->home('follower');
	}
	public function API_favorite()
	{
		$this->home('favorite');
	}

	public function ACTION_findpwd()
	{
		Captcha::check() or Script::code(0, 'iCMS:captcha:error', 'captcha', 'json');

		$uid = (int) $_POST['uid'];
		$auth = Request::post('auth');
		if ($auth && $uid) {
			//print_r($_POST);
			$authcode = rawurldecode($auth);
			$authcode = base64_decode($authcode);
			$authcode = auth_decode($authcode);

			if (empty($authcode)) {
				Script::code(0, 'user:findpwd:error', 'uname', 'json');
			}
			list($uid, $account, $password, $timeline) = explode(USER_AUTHASH, $authcode);
			$uid = (int)$uid;
			$now = time();
			if ($now - $timeline > 86400) {
				Script::code(0, 'user:findpwd:error', 'time', 'json');
			}
			$user = User::get($uid, false);
			if ($account != $user['account'] || $password != $user['password']) {
				Script::code(0, 'user:findpwd:error', 'user', 'json');
			}
			$rstpassword = md5(trim($_POST['rstpassword']));
			if ($rstpassword == $user['password']) {
				Script::code(0, 'user:findpwd:same', 'password', 'json');
			}
			UserModel::update(array('password' => $rstpassword), array('uid' => $uid));
			Script::code(1, 'user:findpwd:success', 0, 'json');
		} else {
			$uname = Request::post('uname');
			$uname or Script::code(0, 'user:findpwd:account:empty', 'uname', 'json');
			$uid = User::check($uname, 'account');
			$uid or Script::code(0, 'user:findpwd:account:noexist', 'uname', 'json');
			$user = User::get($uid, false);
			$user or Script::code(0, 'user:findpwd:account:noexist', 'uname', 'json');

			$authcode = auth_encode($uid .
				USER_AUTHASH . $user['account'] .
				USER_AUTHASH . $user['password'] .
				USER_AUTHASH . time());
			$authcode = base64_encode($authcode);
			$authcode = rawurlencode($authcode);
			$find_url = Route::routing('user:findpwd', 'auth=' . $authcode);
			$config = Config::get('mail');
			$config['title'] = Config::get('site.name');
			$config['subject'] = Lang::get('user:findpwd:subject', $config['title']);
			$config['body'] = Lang::get(
				'user:findpwd:body',
				array($user['nickname'], $config['title'], $find_url, $find_url, $config['replyto'])
			);
			$config['address'] = array(
				array($user['account'], $user['nickname']),
			);
			//var_dump(iCMS::$config);
			$result = Vendor::run('SendMail', array($config));

			if ($result === true) {
				Script::code(1, 'user:findpwd:send:success', 'mail', 'json');
			} else {
				Script::code(0, 'user:findpwd:send:failure', 'mail', 'json');
			}
		}
	}


	public function ACTION_report()
	{
		$this->auth or Script::code(0, 'iCMS:!login', 0, 'json');

		$iid = (int) $_POST['iid'];
		$uid = (int) $_POST['userid'];
		$appid = (int) $_POST['appid'];
		$reason = (int) $_POST['reason'];
		$content = Request::post('content');

		$iid or Script::code(0, 'iCMS:error', 0, 'json');
		$uid or Script::code(0, 'iCMS:error', 0, 'json');
		$reason or $content or Script::code(0, 'iCMS:report:empty', 0, 'json');

		$addtime = time();
		$ip = Request::ip();
		$userid = User::$id;
		$status = 0;

		$fields = array('appid', 'userid', 'iid', 'uid', 'reason', 'content', 'ip', 'addtime', 'status');
		$data = compact($fields);
		$id = UserReportModel::create($data, true);
		Script::code(1, 'iCMS:report:success', $id, 'json');
	}

	public function ACTION_follow()
	{
		$this->auth or Script::code(0, 'iCMS:!login', 0, 'json');

		$uid = (int) User::$id;
		$name = User::$nickname;
		$fuid = (int) $_POST['uid'];
		$follow = (bool) $_POST['follow'];

		$uid or Script::code(0, 'iCMS:error', 0, 'json');
		$fuid or Script::code(0, 'iCMS:error', 0, 'json');

		if ($follow) {
			//1 关注
			$uid == $fuid && Script::code(0, 'user:follow:self', 0, 'json');
			$check = UserFollow::is($uid, $fuid);
			if ($check) {
				Script::code(1, 'user:follow:success', 0, 'json');
			} else {
				$fname  = User::value($fuid, 'nickname');
				$fields = array('uid', 'name', 'fuid', 'fname');
				$data   = compact($fields);
				UserFollowModel::create($data, true);
				User::updateInc('follow', $uid);
				User::updateInc('fans', $fuid);
				Script::code(1, 'user:follow:success', 0, 'json');
			}
		} else {
			UserFollowModel::delete(compact('uid', 'fuid'));
			User::updateDec('follow', $uid);
			User::updateDec('fans', $fuid);
			Script::code(1, 0, 0, 'json');
		}
	}

	public function API_hits($uid = null)
	{
		$uid === null && $uid = (int) $_GET['uid'];
		$uid && AppsApp::updateHits('user', $uid, 'uid');
	}
	public function API_check()
	{
		$name  = Request::get('name');
		$value = Request::get('value');
		$a = Script::code(1, '', $name, 'array');
		switch ($name) {
			case 'account':
				if (!preg_match("/^[\w\-\.]+@[\w\-]+(\.\w+)+$/i", $value)) {
					$a = Script::code(0, 'user:account:error', 'account', 'array');
				} else {
					if (User::check($value, 'account')) {
						$a = Script::code(0, 'user:account:exist', 'account', 'array');
					}
				}
				break;
			case 'nickname':
				if (preg_match("/\d/", $value[0]) || iString::strlen($value) > 20 || iString::strlen($value) < 4) {
					$a = Script::code(0, 'user:nickname:error', 'nickname', 'array');
				} else {
					if (User::check($value, 'nickname')) {
						$a = Script::code(0, 'user:nickname:exist', 'nickname', 'array');
					}
				}
				break;
			case 'password':
				strlen($value) < 6 && $a = Script::code(0, 'user:password:error', 'password', 'array');
				break;
			case 'captcha':
				Captcha::check($value, false) or $a = Script::code(0, 'iCMS:captcha:error', 'captcha', 'array');
				break;
		}
		iJson::display($a);
	}

	public function ACTION_status($uid = 0)
	{
		$user = User::status();
		if ($user) {

			$status = array(
				'code'        => 1,
				'user'        => $user,
				'message_num' => MessageApp::_count($user['uid']),
			);

			View::assign('status', $status);
			View::display('iCMS://user/api.status.htm');
		} else {
			iJson::error('user:nologin', $this->forward);
		}
	}

	public function API_findpwd()
	{
		$auth = Request::get('auth');
		if ($auth) {
			$authcode = rawurldecode($auth);
			$authcode = base64_decode($authcode);
			$authcode = auth_decode($authcode);

			if (empty($authcode)) {
				exit;
			}
			list($uid, $account, $password, $timeline) = explode(USER_AUTHASH, $authcode);
			$now = time();
			if ($now - $timeline > 86400) {
				exit;
			}
			$user = User::get($uid, false);
			if ($account != $user['account'] || $password != $user['password']) {
				exit;
			}
			unset($user['password']);
			View::assign('auth', $auth);
			View::assign('user', (array) $user);
			View::display('iCMS://user/resetpwd.htm');
		} else {
			View::display('iCMS://user/findpwd.htm');
		}
	}
	
	public function API_collections()
	{
		//View::display('iCMS://user/card.htm');
	}
	public function API_ucard()
	{
		UserCP::user();
		if ($this->auth) {
			$secondary = $this->ucard_info();
			View::assign('secondary', $secondary);
		}
		View::display('iCMS://user/user.card.htm');
	}

	public function ucard_info()
	{
		if ($this->uid == User::$id) {
			return;
		}

		$follow = UserFollow::gets(User::$id, 'all'); //你的所有关注者
		$fans = UserFollow::gets('all', $this->uid); //他的所有粉丝
		$links = array();
		foreach ((array) $fans as $uid => $name) {
			if ($follow[$uid]) {
				$url = User::route($uid, "url");
				$links[$uid] = '<a href="' . $url . '" class="user-link" title="' . $name . '">' . $name . '</a>';
			}
		}
		if (empty($links)) {
			return;
		}
		$_count = count($links);
		$text = Lang::get('user:follow:text1');
		if ($_count > 3) {
			$links = array_slice($links, 0, 3);
			$text = Lang::get(array('user:follow:text2', $_count));
		}
		return implode('、', $links) . $text;
	}

	public function openid()
	{
		if (!isset($_GET['sign'])) {
			return;
		}
		$sign  = strtoupper($_GET['sign']);
		$code  = $_GET['code'];
		$state = $_GET['state'];
		$bind  = $sign;
		$platform_map = array('WX' => 1, 'QQ' => 2, 'WB' => 3, 'TB' => 4);
		$platform     = $platform_map[$sign];

		if ($platform) {
			$class_name   = 'oauth_' . $sign;
			require_once __DIR__ . '/oauth/' . $class_name . '.class.php';
			$open = new $class_name;
			$open->appid = User::$config['open'][$sign]['appid'];
			$open->appkey = User::$config['open'][$sign]['appkey'];
			$redirect_uri = rtrim(User::$config['open'][$sign]['redirect'], '/');
			$open->url = User::getLoginUrl($redirect_uri) . 'sign=' . $sign;
			$this->forward && $open->url .= '&forward=' . urlencode($this->forward);

			if (isset($_GET['bind']) && $_GET['bind'] == $sign) {
				$open->get_openid();
			} else {
				$open->callback();
			}

			$userid = user_openid::uid($open->openid, $platform);
			if ($userid) {
				$user = User::get($userid, false);
				User::setAuth($user['account'], $user['password'], array(
					'uid' => $userid,
					'account' => $user['account'],
					'nickname' => $user['nickname'],
					'status' => $user['status'],
				));
				$open->cleancookie();
				Helper::redirect($this->forward);
			} else {
				if (isset($_GET['bind'])) {
					$user = array();
					$user['openid'] = $open->openid;
					$user['platform'] = $platform;
					$open->cleancookie();
					View::assign('user', $user);
					View::display('iCMS://user/login.htm');
				} else {
					$user = $open->get_user_info();
					$user['openid'] = $open->openid;
					$user['platform'] = $platform;
					User::check($user['nickname'], 'nickname') && $user['nickname'] = $sign . '_' . $user['nickname'];
					$open->cleancookie();
					View::assign('user', $user);
					View::assign('query', compact(array('sign', 'code', 'state', 'bind')));
					View::display('iCMS://user/register.htm');
				}
				exit;
			}
		}
	}

	public static function at_user_list($content)
	{
		return self::at($content);
	}
	public static function at_content($content)
	{
		return self::at($content, false);
	}
	public static function at($content, $user = true)
	{
		preg_match_all('/@(.+?[^@])\s/is', str_replace('@', "\n@", $content), $matches);
		$user_list = array_unique($matches[1]);
		if ($user_list) {
			foreach ($user_list as $key => $nk) {
				$userArray[$key] = array('nickname' => $nk);
				if (!$user) {
					$search[$nk]  = '@' . $nk;
					$replace[$nk] = '@' . $nk;
				}
			}
			$values = array_column($userArray, 'nickname');
			$values && $user_data = (array) User::get($values, true, 'nickname');
			foreach ((array)$user_data as $key => $value) {
				if (!$user) {
					$U = User::info($value->uid, $value->nickname);
					$replace[$value->nickname] = $U['at'];
				} else {
					$remindUser[$value->uid] = $value->nickname;
				}
			}
			!$user && $content = str_replace($search, $replace, $content);
		}
		return $user ? $remindUser : $content;
	}
	public static function run_method($a, $do, $prefix)
	{
		if (in_array($do, $a->methods)) {
			$method = $prefix . '_' . $do;
			$class_methods = get_class_methods($a);
			if (in_array($method, $class_methods)) {
				$a->$method();
			}
		}
	}
}
