<?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;
use Modules\Account\Models\Family;
use Modules\Account\Models\FamilyMember;
use Illuminate\Support\Facades\DB;

class AdminStatisticsService {

	/**
	 * @title 获取概览统计
	 *
	 * @param Request $request
	 * @return array
	 */
	public function getOverview($request) {
		$year = $request->input('year', date('Y'));
		$month = $request->input('month', date('m'));
		$startDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
		$endDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-31';

		// 总账单数
		$totalBills = Bill::count();

		// 当月账单数
		$monthBills = Bill::whereBetween('bill_date', [$startDate, $endDate])->count();

		// 总收入
		$totalIncome = (float)Bill::where('type', 'income')->sum('amount');

		// 总支出
		$totalExpense = (float)Bill::where('type', 'expense')->sum('amount');

		// 当月收入
		$monthIncome = (float)Bill::where('type', 'income')
			->whereBetween('bill_date', [$startDate, $endDate])
			->sum('amount');

		// 当月支出
		$monthExpense = (float)Bill::where('type', 'expense')
			->whereBetween('bill_date', [$startDate, $endDate])
			->sum('amount');

		// 总用户数
		$totalUsers = DB::table('auth_users')->count();

		// 总家庭数
		$totalFamilies = Family::count();

		// 活跃用户数（本月有记账的用户）
		$activeUsers = Bill::whereBetween('bill_date', [$startDate, $endDate])
			->distinct('user_id')
			->count('user_id');

		// 活跃家庭数（本月有记账的家庭）
		$activeFamilies = Bill::whereBetween('bill_date', [$startDate, $endDate])
			->whereNotNull('family_id')
			->distinct('family_id')
			->count('family_id');

		return [
			'total_bills' => $totalBills,
			'month_bills' => $monthBills,
			'total_income' => $totalIncome,
			'total_expense' => $totalExpense,
			'total_balance' => $totalIncome - $totalExpense,
			'month_income' => $monthIncome,
			'month_expense' => $monthExpense,
			'month_balance' => $monthIncome - $monthExpense,
			'total_users' => $totalUsers,
			'total_families' => $totalFamilies,
			'active_users' => $activeUsers,
			'active_families' => $activeFamilies
		];
	}

	/**
	 * @title 获取趋势统计
	 *
	 * @param Request $request
	 * @return array
	 */
	public function getTrend($request) {
		$type = $request->input('type', 'month'); // month 或 year
		$year = $request->input('year', date('Y'));
		$months = $request->input('months', 12);
		$years = $request->input('years', 5);

		if ($type === 'month') {
			// 月度趋势
			$data = [];
			for ($i = $months - 1; $i >= 0; $i--) {
				$date = date('Y-m', strtotime("-$i months"));
				$startDate = $date . '-01';
				$endDate = date('Y-m-t', strtotime($date));

				$income = (float)Bill::where('type', 'income')
					->whereBetween('bill_date', [$startDate, $endDate])
					->sum('amount');

				$expense = (float)Bill::where('type', 'expense')
					->whereBetween('bill_date', [$startDate, $endDate])
					->sum('amount');

				$count = Bill::whereBetween('bill_date', [$startDate, $endDate])->count();

				$data[] = [
					'date' => $date,
					'income' => $income,
					'expense' => $expense,
					'balance' => $income - $expense,
					'count' => $count
				];
			}
		} else {
			// 年度趋势
			$data = [];
			for ($i = $years - 1; $i >= 0; $i--) {
				$currentYear = date('Y') - $i;

				$income = (float)Bill::where('type', 'income')
					->whereYear('bill_date', $currentYear)
					->sum('amount');

				$expense = (float)Bill::where('type', 'expense')
					->whereYear('bill_date', $currentYear)
					->sum('amount');

				$count = Bill::whereYear('bill_date', $currentYear)->count();

				$data[] = [
					'year' => $currentYear,
					'income' => $income,
					'expense' => $expense,
					'balance' => $income - $expense,
					'count' => $count
				];
			}
		}

		return $data;
	}

	/**
	 * @title 获取分类统计
	 *
	 * @param Request $request
	 * @return array
	 */
	public function getCategoryStatistics($request) {
		$type = $request->input('type', 'expense'); // income 或 expense
		$year = $request->input('year', date('Y'));
		$month = $request->input('month');

		$query = Bill::where('type', $type);

		if ($year && $month) {
			$startDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
			$endDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-31';
			$query->whereBetween('bill_date', [$startDate, $endDate]);
		} else {
			$query->whereYear('bill_date', $year);
		}

		$bills = $query->get();

		// 按分类汇总
		$data = $bills->groupBy('category')->map(function ($items) {
			return [
				'category' => $items->first()->category,
				'count' => $items->count(),
				'amount' => (float)$items->sum('amount')
			];
		})->sortByDesc('amount')->values();

		// 计算总金额和占比
		$totalAmount = $data->sum('amount');
		$data = $data->map(function ($item) use ($totalAmount) {
			$item['percentage'] = $totalAmount > 0 ? round($item['amount'] / $totalAmount * 100, 2) : 0;
			return $item;
		});

		return [
			'type' => $type,
			'total_amount' => (float)$totalAmount,
			'total_count' => $data->sum('count'),
			'categories' => $data
		];
	}

	/**
	 * @title 获取用户统计
	 *
	 * @param Request $request
	 * @return array
	 */
	public function getUserStatistics($request) {
		$limit = $request->input('limit', 20);
		$type = $request->input('type', 'expense'); // income 或 expense
		$year = $request->input('year', date('Y'));
		$month = $request->input('month');

		$query = Bill::select('user_id')
			->selectRaw('COUNT(*) as bill_count')
			->selectRaw('SUM(CASE WHEN type = "income" THEN amount ELSE 0 END) as total_income')
			->selectRaw('SUM(CASE WHEN type = "expense" THEN amount ELSE 0 END) as total_expense')
			->selectRaw('SUM(CASE WHEN type = "income" THEN amount ELSE 0 END) - SUM(CASE WHEN type = "expense" THEN amount ELSE 0 END) as balance')
			->with('user:uid,nickname,username');

		if ($year && $month) {
			$startDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
			$endDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-31';
			$query->whereBetween('bill_date', [$startDate, $endDate]);
		} else {
			$query->whereYear('bill_date', $year);
		}

		$users = $query->groupBy('user_id')
			->orderBy($type === 'income' ? 'total_income' : 'total_expense', 'desc')
			->limit($limit)
			->get();

		return [
			'type' => $type,
			'users' => $users->map(function ($user) {
				return [
					'user_id' => $user->user_id,
					'name' => $user->user->nickname ?? $user->user->username,
					'username' => $user->user->username,
					'bill_count' => $user->bill_count,
					'total_income' => (float)$user->total_income,
					'total_expense' => (float)$user->total_expense,
					'balance' => (float)$user->balance
				];
			})
		];
	}

	/**
	 * @title 获取家庭统计
	 *
	 * @param Request $request
	 * @return array
	 */
	public function getFamilyStatistics($request) {
		$limit = $request->input('limit', 20);
		$type = $request->input('type', 'expense'); // income 或 expense
		$year = $request->input('year', date('Y'));
		$month = $request->input('month');

		$query = Bill::select('family_id')
			->selectRaw('COUNT(*) as bill_count')
			->selectRaw('SUM(CASE WHEN type = "income" THEN amount ELSE 0 END) as total_income')
			->selectRaw('SUM(CASE WHEN type = "expense" THEN amount ELSE 0 END) as total_expense')
			->selectRaw('SUM(CASE WHEN type = "income" THEN amount ELSE 0 END) - SUM(CASE WHEN type = "expense" THEN amount ELSE 0 END) as balance')
			->whereNotNull('family_id')
			->with('family:id,name,owner_id');

		if ($year && $month) {
			$startDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
			$endDate = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-31';
			$query->whereBetween('bill_date', [$startDate, $endDate]);
		} else {
			$query->whereYear('bill_date', $year);
		}

		$families = $query->groupBy('family_id')
			->orderBy($type === 'income' ? 'total_income' : 'total_expense', 'desc')
			->limit($limit)
			->get();

		// 获取成员数量
		$familyIds = $families->pluck('family_id')->toArray();
		$memberCounts = FamilyMember::whereIn('family_id', $familyIds)
			->selectRaw('family_id, COUNT(*) as member_count')
			->groupBy('family_id')
			->pluck('member_count', 'family_id');

		return [
			'type' => $type,
			'families' => $families->map(function ($family) use ($memberCounts) {
				return [
					'family_id' => $family->family_id,
					'name' => $family->family->name,
					'member_count' => $memberCounts[$family->family_id] ?? 0,
					'bill_count' => $family->bill_count,
					'total_income' => (float)$family->total_income,
					'total_expense' => (float)$family->total_expense,
					'balance' => (float)$family->balance
				];
			})
		];
	}
}
