<?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\Account\Services;

use Illuminate\Http\Request;
use Modules\Account\Models\Bill;

class AdminBillService {

	/**
	 * @title 获取账单列表
	 *
	 * @param Request $request
	 * @return void
	 */
	public function getDataList($request) {
		$map = [];

		// 用户筛选
		if ($request->filled('user_id')) {
			$map[] = ['user_id', '=', $request->input('user_id')];
		}

		// 家庭筛选
		if ($request->filled('family_id')) {
			$map[] = ['family_id', '=', $request->input('family_id')];
		}

		// 类型筛选
		if ($request->filled('type') && in_array($request->input('type'), ['income', 'expense'])) {
			$map[] = ['type', '=', $request->input('type')];
		}

		// 分类筛选
		if ($request->filled('category')) {
			$map[] = ['category', 'like', '%' . $request->input('category') . '%'];
		}

		// 支付方式筛选
		if ($request->filled('payment_method')) {
			$map[] = ['payment_method', '=', $request->input('payment_method')];
		}

		// 备注搜索
		if ($request->filled('remark')) {
			$map[] = ['remark', 'like', '%' . $request->input('remark') . '%'];
		}

		// 日期范围筛选
		if ($request->filled('start_date')) {
			$map[] = ['bill_date', '>=', $request->input('start_date')];
		}
		if ($request->filled('end_date')) {
			$map[] = ['bill_date', '<=', $request->input('end_date')];
		}

		// 年月筛选
		if ($request->filled('year') && $request->filled('month')) {
			$startDate = $request->input('year') . '-' . str_pad($request->input('month'), 2, '0', STR_PAD_LEFT) . '-01';
			$endDate = $request->input('year') . '-' . str_pad($request->input('month'), 2, '0', STR_PAD_LEFT) . '-31';
			// 清除之前的日期条件
			$map = array_filter($map, function($item) {
				return !isset($item[0]) || !in_array($item[0], ['bill_date']);
			});
			$map[] = ['bill_date', '>=', $startDate];
			$map[] = ['bill_date', '<=', $endDate];
		}

		$query = Bill::with(['user:uid,nickname,username', 'family:id,name']);

		$query->where($map);

		// 排序
		$query->orderBy($request->input('order', 'bill_date'), $request->input('sort', 'desc'));

		// 分页
		if ($request->filled('page')) {
			$data = [
				'total' => $query->count(),
				'page' => $request->input('page', 1),
				'data' => $query->offset($request->input('offset', 0))
					->limit($request->input('limit', 10))
					->get(),
			];
		} else {
			$data = $query->get();
		}

		// 计算统计数据
		if ($request->filled('page')) {
			$statsQuery = Bill::query()->where($map);
			$totalExpense = (clone $statsQuery)->where('type', 'expense')->sum('amount');
			$totalIncome = (clone $statsQuery)->where('type', 'income')->sum('amount');
			$data['statistics'] = [
				'total_expense' => (float)$totalExpense,
				'total_income' => (float)$totalIncome,
				'total_balance' => (float)($totalIncome - $totalExpense),
				'total_count' => $data['total']
			];
		}

		return $data;
	}

	/**
	 * @title 添加账单
	 *
	 * @param Request $request
	 * @return void
	 */
	public function create($request) {
		$request->validate([
			'user_id' => 'required|integer',
			'type' => 'required|in:income,expense',
			'amount' => 'required|numeric|min:0.01',
			'category_id' => 'required|integer',
			'payment_method' => 'nullable|string|in:微信,支付宝,银行卡,现金,其他',
			'remark' => 'nullable|string|max:255',
			'date' => 'required|date',
			'family_id' => 'nullable|integer|exists:account_families,id'
		], [
			'user_id.required' => '请选择用户',
			'type.required' => '请选择账单类型',
			'amount.required' => '请输入金额',
			'category_id.required' => '请选择分类',
			'date.required' => '请选择日期'
		]);

		$data = $request->all();

		// 将category_id转换为category字符串
		$categoryMap = $this->getCategoryMap($data['type']);
		if (!isset($categoryMap[$data['category_id']])) {
			throw new \Exception('分类不存在');
		}

		$data['category'] = $categoryMap[$data['category_id']];
		$data['bill_date'] = $data['date'];

		// 移除前端字段
		unset($data['category_id'], $data['date']);

		return Bill::create($data);
	}

	/**
	 * @title 更新账单
	 *
	 * @param Request $request
	 * @return void
	 */
	public function update($request) {
		$request->validate([
			'id' => 'required|integer',
			'user_id' => 'required|integer',
			'type' => 'required|in:income,expense',
			'amount' => 'required|numeric|min:0.01',
			'category_id' => 'required|integer',
			'payment_method' => 'nullable|string|in:微信,支付宝,银行卡,现金,其他',
			'remark' => 'nullable|string|max:255',
			'date' => 'required|date',
			'family_id' => 'nullable|integer|exists:account_families,id'
		], [
			'id.required' => '请提供账单ID',
			'user_id.required' => '请选择用户',
			'type.required' => '请选择账单类型',
			'amount.required' => '请输入金额',
			'category_id.required' => '请选择分类',
			'date.required' => '请选择日期'
		]);

		$bill = Bill::findOrFail($request->input('id'));
		$data = $request->all();

		// 将category_id转换为category字符串
		$categoryMap = $this->getCategoryMap($data['type']);
		if (!isset($categoryMap[$data['category_id']])) {
			throw new \Exception('分类不存在');
		}

		$data['category'] = $categoryMap[$data['category_id']];
		$data['bill_date'] = $data['date'];

		// 移除前端字段
		unset($data['category_id'], $data['date'], $data['id']);

		$bill->update($data);

		return $bill;
	}

	/**
	 * @title 删除账单
	 *
	 * @param Request $request
	 * @return void
	 */
	public function delete($request) {
		if ($request->filled('id')) {
			try {
				$bill = Bill::findOrFail($request->input('id'));
				$bill->delete();
			} catch (\Throwable $th) {
				throw new \Exception("账单不存在！", 1);
			}
		}

		if ($request->filled('ids')) {
			try {
				$bill = Bill::whereIn('id', $request->input('ids'));
				$bill->delete();
			} catch (\Throwable $th) {
				throw new \Exception($th->getMessage(), 1);
			}
		}

		return $bill;
	}

	/**
	 * @title 账单详情
	 *
	 * @param Request $request
	 * @return void
	 */
	public function detail($request) {
		$id = $request->input('id');

		$bill = Bill::with(['user:uid,nickname,username', 'family:id,name,owner_id'])
			->findOrFail($id);

		return $bill;
	}

	/**
	 * @title 获取分类映射
	 *
	 * @param string $type
	 * @return array
	 */
	private function getCategoryMap($type) {
		if ($type === 'income') {
			return [
				101 => '工资',
				102 => '奖金',
				103 => '投资',
				104 => '兼职',
				105 => '其他'
			];
		} else {
			return [
				1 => '餐饮',
				2 => '交通',
				3 => '购物',
				4 => '娱乐',
				5 => '医疗',
				6 => '教育',
				7 => '居住',
				8 => '其他'
			];
		}
	}

	/**
	 * @title 获取分类列表
	 *
	 * @return array
	 */
	public function getCategoryList() {
		return [
			'expense' => [
				['id' => 1, 'name' => '餐饮'],
				['id' => 2, 'name' => '交通'],
				['id' => 3, 'name' => '购物'],
				['id' => 4, 'name' => '娱乐'],
				['id' => 5, 'name' => '医疗'],
				['id' => 6, 'name' => '教育'],
				['id' => 7, 'name' => '居住'],
				['id' => 8, 'name' => '其他']
			],
			'income' => [
				['id' => 101, 'name' => '工资'],
				['id' => 102, 'name' => '奖金'],
				['id' => 103, 'name' => '投资'],
				['id' => 104, 'name' => '兼职'],
				['id' => 105, 'name' => '其他']
			]
		];
	}

	/**
	 * @title 获取支付方式列表
	 *
	 * @return array
	 */
	public function getPaymentMethods() {
		return [
			['value' => '微信', 'label' => '微信'],
			['value' => '支付宝', 'label' => '支付宝'],
			['value' => '银行卡', 'label' => '银行卡'],
			['value' => '现金', 'label' => '现金'],
			['value' => '其他', 'label' => '其他']
		];
	}
}
