<?php
// +----------------------------------------------------------------------
// | SentCMS [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2024 http://www.tensent.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: molong <molong@tensent.cn> <http://www.tensent.cn>
// +----------------------------------------------------------------------
namespace Modules\Member\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use App\Support\Time;
use Modules\Member\Models\MemberAccount;
use Modules\Member\Models\Member;
use Modules\Wechat\Services\TransferService;

class AccountService {

	/**
	 * @title 获取会员列表
	 *
	 * @param [type] $request
	 * @return void
	 */
	public function getDataList($request){
		$map = [];
		$query = MemberAccount::with(['order:id,order_id,title,cover,total_price,total_integral,created_at', 'order.order:id,order_no', 'bank']);

		if ($request->filled('pay_type')) {
			$map[] = ['pay_type', '=', $request->input('pay_type')];
		}
		if ($request->filled('is_user')){
			$map[] = ['member_id', '=', auth('api')->user()['uid']];
			$query->whereIn('type', ['income', 'withdraw', 'transfer']);
		}

		if ($request->filled('is_admin') && auth('admin')->user()) {
			$map[] = ['member_id', '=', auth('admin')->user()['uid']];
			$query->whereIn('type', ['service_income', 'service_withdraw', 'service_transfer']);
		}else{
			$query->whereIn('type', ['income', 'withdraw', 'transfer']);
		}

		if ($request->filled('status')) {
			if ($request->input('status') == 'dsh') {
				$map[] = ['status', '=', 0];
				$map[] = ['amount', '<', 0];
			} elseif ($request->input('status') == 'tgtx'){
				$map[] = ['status', '=', 3];
				$map[] = ['amount', '<', 0];
			}elseif ($request->input('status') == 'ytx'){
				$map[] = ['status', '=', 2];
				$map[] = ['amount', '>', 0];
			}elseif ($request->input('status') == 'dtx'){
				$query->whereIn('status', [0, 1])->where('amount', '>', 0);
			}
		}
		if ($request->filled('type')) {
			if (is_string($request->input('type'))){
				$map[] = ['type', '=', $request->input('type')];
			}else if (is_array($request->input('type'))){
				$query->whereIn('type', $request->input('type'));
			}
		}

		if ($request->filled('date')) {
			$date = Time::month($request->input('date'));
			$query->where(function($query) use ($date){
				$query->whereBetween('created_at', [date('Y-m-d H:i:s', $date[0]), date('Y-m-d H:i:s', $date[1])]);
			});
		}
		$query = $query->where($map)->orderBy('id', 'desc');

		if ($request->filled('username')) {
			$query->whereHas('member', function($query) use ($request){
				$query->where('username', 'like', '%' . $request->input('username') . '%');
			});
		}
		if ($request->filled('mobile')) {
			$query->whereHas('member', function($query) use ($request){
				$query->where('mobile', 'like', '%' . $request->input('mobile') . '%');
			});
		}
		if ($request->filled('store_title')) {
			$query->whereHas('store', function($query) use ($request){
				$query->where('title', 'like', '%' . $request->input('store_title') . '%');
			});
		}

		if($request->filled('page')){
			$data = [
				'total' => $query->count(),
				'page' => $request->input('page', 1),
				'data' => $query->offset($request->input('offset', 0))->limit($request->input('limit', 30))->get()->each(function($item){
					if (in_array($item->type, ['income', 'withdraw'])){
						$item->member = $item->member()->select(['uid', 'username', 'nickname', 'avatar'])->first();
					}else if (in_array($item->type, ['service_income', 'service_withdraw'])){
						$item->member = $item->admin()->select(['uid', 'username', 'nickname', 'avatar'])->first();
					}else{
						$item->member = $item->member()->select(['uid', 'username', 'nickname', 'avatar'])->first();
					}
				}),
			];
		}else{
			$data = $query->limit($request->input('limit', 30))->get();
		}
		return $data;
	}

	/**
	 * @title 创建资金记录
	 *
	 * @param Request $request
	 * @param MemberService $service
	 * @return void
	 */
	public function createAccount($store_id, $order_id, $member_id, $type, $account_type = 'order', $amount = 0, $remark = ''){
		if ($order_id > 0) {
			$account = MemberAccount::where('order_id', '=', $order_id)->where('member_id', '=', $member_id)->where('type', '=', $type)->where('account_type', '=', $account_type)->first();
			if($account){
				return $account;
			}
		}
		$last_account = MemberAccount::where('member_id', '=', $member_id)->where('type', '=', $type)->orderBy('id', 'desc')->first();
		$af_amount = $amount;
		$bf_amount = 0;
		if($last_account){
			$af_amount = $type == 'income' ? $last_account['af_amount'] + $amount : $last_account['af_amount'] - $amount;
			$bf_amount = $last_account['af_amount'];
		}
		$data = [
			'store_id' => $store_id,
			'order_id' => $order_id,
			'member_id' => $member_id,
			'type' => $type,
			'account_type' => $account_type,
			'amount' => $amount,
			'bf_amount' => $bf_amount,
			'af_amount' => $af_amount,
			'remark' => $remark,
		];

		if($type == 'income'){
			$member = Member::find($member_id);
			$member->money = $member['money'] + $amount;
			$member->save();
		}else if($type == 'transfer'){
			$member = Member::find($member_id);
			$member->money = $member['money'] - $amount;

			if ($member['money'] < 0){
				throw new \Exception("会员余额不足!", 0);
			}
			$member->save();
		}

		$account = MemberAccount::create($data);
		return $account;
	}

	/**
	 * @title 修改会员
	 *
	 * @param Request $request
	 * @param MemberService $service
	 * @return void
	 */
	public function update($request){
		$request->validate([
			'title' => 'required|max:255',
			'name' => 'required|max:255|alpha_dash:ascii|unique:member_level,name,' . $request->input('id'),
		]);

		try {
			$account = MemberAccount::findOrFail($request->input('id'));
		} catch (\Throwable $th) {
			throw new \Exception("会员不存在！", 1);
		}

		$data = [
			'title'=> $request->input('title', ''),
			'name' => $request->input('name', ''),
			'icon' => $request->input('icon', ''),
			'sort' => $request->input('sort', 0),
			'status' => $request->input('status', 1),
			'remark' => $request->input('remark', ''),
		];
		$account->update($data);
		return $account;
	}

	public function delete($request){
		if($request->filled('id')){
			try {
				$account = MemberAccount::findOrFail($request->input('id'));
			} catch (\Throwable $th) {
				throw new \Exception("会员等级不存在！", 1);
			}
			$account->delete();
		}
		if($request->filled('ids')){
			try {
				$account = MemberAccount::whereIn('id', $request->input('ids'));

				$account->delete();
			} catch (\Throwable $th) {
				throw new \Exception($th->getMessage(), 1);
			}
		}

		return $account;
	}

	public function withdrawApply($request){
		$request->validate([
			'amount' => 'required|numeric|min:1',
			'pay_type' => ['required', Rule::in(['wechat', 'alipay', 'bank'])],
			'bank_id' => Rule::requiredIf($request->input('pay_type') == 'bank'),
		], [
			'amount.required' => '请输入提现金额',
			'amount.min' => '提现金额不能小于1元',
			'pay_type.required' => '请选择提现方式',
			'pay_type.in' => '选择的提现方式有误',
			'bank_id.required' => '请选择提现银行',
		]);

		$member = auth('api')->user();

		if ($member['money'] < $request->input('amount')) {
			throw new \Exception("余额不足，无法提现", 0);
		}

		$config = cache()->get('config');

		if ($config['low_withdraw_amount'] > $request->input('amount')) {
			throw new \Exception("提现金额不能小于" . $config['low_withdraw_amount'] . "元", 0);
		}

		$data = [
			'order_id' => 0,
			'store_id' => 0,
			'member_id' => $member['uid'],
			'amount' => $request->input('amount'),
			'type' => 'withdraw',
			'account_type' => 'withdraw',
			'af_amount' => $member['money'],
			'bf_amount' => bcsub($member['money'], $request->input('amount'), 2),
			'fee_rate' => $config['withdraw_fee_rate'],
			'actual_amount' => bcsub($request->input('amount'), bcmul($request->input('amount'), bcdiv($config['withdraw_fee_rate'], 100, 2), 2), 2),
			'pay_type' => $request->input('pay_type'),
			'bank_id' => $request->input('bank_id', 0),
			'status' => 0,
			'request_no' => str_replace('-', '', Str::orderedUuid()),
			'remark' => $request->input('remark', '用户提现'),
		];

		$account = new MemberAccount();

		foreach($account->setFilterFields($data) as $key => $value){
			$account->$key = $value;
		}

		$account->save();

		//扣除余额
		$user = Member::find($member['uid']);
		$user->money = bcsub($user->money, $request->input('amount'), 2);
		$user->save();

		return $account;
	}

	public function withdraw($request){
		$account = MemberAccount::find($request->input('id'));
		if(!$account){
			throw new \Exception("提现记录不存在！", 0);
		}
		if(in_array($account->status, [1,2])){
			throw new \Exception("提现记录已处理！", 0);
		}

		$member = Member::where('uid', $account->member_id)->first();

		if($account->pay_type=="wechat"){//
			$result = TransferService::transfer($account->bank_realname,$account->request_no,$account->actual_amount,$member['username']);
			if(isset($result['code'])){
				throw new \Exception('异常：'.$result['code'].' '.$result['message'], 0);
			}
			MemberAccount::where(['id'=>$account->id])->update(['status'=>1,'out_batch_no'=>$result]);
		}else if($account->pay_type=="bank"){
			throw new \Exception("银行卡在开发中！", 0);
		}else {
			throw new \Exception("该提现方式不存在！", 0);
		}
		return $account;
	}

	/**
	 * @title 获取会员统计
	 *
	 * @param [type] $request
	 * @return void
	 */
	public function getAccountCount($request){
		$map = [];
		$map[] = ['member_id', '=', auth('api')->user()['uid']];
		// if($request->filled('date')){
		// 	//自己的账单
		// 	$map[] =['created_at', 'between', [Carbon::parse($request->input('date'))->timestamp, Carbon::parse($request->input('date'))->timestamp]];
		// }

		$income = MemberAccount::where($map)->where('type', '=', 0)->sum('amount');
		$expend = MemberAccount::where($map)->where('type', '=', 1)->sum('amount');
		return ['income' => $income, 'expend' => $expend];
	}
}