<?php

namespace App\Http\Controllers\Admin\Dashboard;

use App\Http\Controllers\Controller;
use App\Models\Expense;
use App\Models\Inventory;
use App\Models\Payroll;
use App\Models\Service;
use App\Models\Transaction;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AnalyticController extends Controller
{
    public function index(): View
    {
        $totalIncome = Transaction::query()->barbershop()->sum('total');
        $totalExpense = Expense::query()->barbershop()->sum('amount');
        $totalPayroll = Payroll::query()->barbershop()->sum('total');
        $totalShaving = Transaction::query()->barbershop()->count();

        $topService = Service::query()->barbershop()->withCount('transactions')->get();

        $paymentMethod = Transaction::select('payment_method', DB::raw('SUM(total) as total_amount'))
            ->barbershop()
            ->groupBy('payment_method')
            ->get();

        $incomeByBarber = User::with('biography')->barbershop()->barber()->withSum('transactions', 'total')->get();

        $transactionByBarber = User::with('biography')->barbershop()->barber()->withCount('transactions')->get();

        $totalAsset = Inventory::query()->barbershop()->sum(DB::raw('quantity * price'));

        $topBarber = User::with('biography')
            ->barbershop()
            ->barber()
            ->withSum('transactions', 'total')
            ->orderBy('transactions_sum_total', 'desc')
            ->first();

        $totalUser = User::query()->barbershop()->count();
        $totalBarber = User::query()->barbershop()->barber()->count();

        return view('pages.admin.dashboard.analytic', [
            'pageTitle' => 'Analitik',
            'totalIncome' => $totalIncome,
            'totalExpense' => $totalExpense + $totalPayroll,
            'totalShaving' => $totalShaving,
            'topService' => $topService,
            'paymentMethod' => $paymentMethod,
            'incomeByBarber' => $incomeByBarber,
            'transactionByBarber' => $transactionByBarber,
            'totalAsset' => $totalAsset,
            'topBarber' => $topBarber,
            'totalUser' => $totalUser,
            'totalBarber' => $totalBarber,
        ]);
    }

    public function filter(Request $request): JsonResponse
    {
        $startDate = $request->start_date;
        $endDate = $request->end_date;

        $totalIncome = Transaction::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->sum('total');

        $totalExpense = Expense::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->sum('amount');

        $totalPayroll = Payroll::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->sum('amount');

        $totalShaving = Transaction::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->count();

        $topService = Service::query()
            ->barbershop()
            ->withCount(['transactions' => function ($query) use ($startDate, $endDate) {
                $query->whereBetween('created_at', [
                    Carbon::parse($startDate)->startOfDay(),
                    Carbon::parse($endDate)->endOfDay(),
                ]);
            }])
            ->get();

        $paymentMethod = Transaction::select('payment_method', DB::raw('SUM(total) as total_amount'))
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->groupBy('payment_method')
            ->get();

        $incomeByBarber = User::with('biography')
            ->barbershop()
            ->barber()
            ->withSum(['transactions' => function ($query) use ($startDate, $endDate) {
                $query->whereBetween('created_at', [
                    Carbon::parse($startDate)->startOfDay(),
                    Carbon::parse($endDate)->endOfDay(),
                ]);
            }], 'total')
            ->get();

        $transactionByBarber = User::with('biography')
            ->barbershop()
            ->barber()
            ->withCount(['transactions' => function ($query) use ($startDate, $endDate) {
                $query->whereBetween('created_at', [
                    Carbon::parse($startDate)->startOfDay(),
                    Carbon::parse($endDate)->endOfDay(),
                ]);
            }])
            ->get();

        $totalAsset = Inventory::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->sum(DB::raw('quantity * price'));

        $topBarber = User::with('biography')
            ->barbershop()
            ->barber()
            ->withSum(['transactions' => function ($query) use ($startDate, $endDate) {
                $query->whereBetween('created_at', [
                    Carbon::parse($startDate)->startOfDay(),
                    Carbon::parse($endDate)->endOfDay(),
                ]);
            }], 'total')
            ->orderBy('transactions_sum_total', 'desc')
            ->first();

        $totalUser = User::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->count();
        $totalBarber = User::query()
            ->barbershop()
            ->whereBetween('created_at', [
                Carbon::parse($startDate)->startOfDay(),
                Carbon::parse($endDate)->endOfDay(),
            ])
            ->barber()
            ->count();

        return response()->json([
            'status' => true,
            'message' => 'Data Successfully Retrieved',
            'data' => [
                'startDate' => $startDate,
                'endDate' => $endDate,
                'totalIncome' => $totalIncome,
                'totalExpense' => $totalExpense + $totalPayroll,
                'totalShaving' => $totalShaving,
                'topService' => $topService,
                'paymentMethod' => $paymentMethod,
                'incomeByBarber' => $incomeByBarber,
                'transactionByBarber' => $transactionByBarber,
                'totalAsset' => $totalAsset,
                'topBarber' => $topBarber,
                'totalUser' => $totalUser,
                'totalBarber' => $totalBarber,
            ],
        ], 200);
    }
}
