<?php

namespace App\Http\Controllers\Backoffice;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Site;
use App\Models\Transaction;
use App\Models\FinanceGroup;
use Carbon\Carbon;
use App\Support\BusinessTime;
use App\Support\SiteCredentialResolver;

class DashboardController extends Controller
{
    public function index(Request $request)
    {
        $user = auth()->user();
        if (!$user) {
            return redirect()->route('backoffice.login');
        }

        // Get date range from request or use current business day window as default
        if ($request->filled('date_from') || $request->filled('date_to')) {
            $dateFromInput = $request->filled('date_from') ? $request->date_from : $request->date_to;
            $dateToInput = $request->filled('date_to') ? $request->date_to : $request->date_from;
            $fromHasTime = is_string($dateFromInput) && preg_match('/\d{2}:\d{2}/', $dateFromInput);
            $toHasTime = is_string($dateToInput) && preg_match('/\d{2}:\d{2}/', $dateToInput);
            $dateFrom = $fromHasTime
                ? Carbon::parse($dateFromInput)
                : BusinessTime::startOfBusinessDay(Carbon::parse($dateFromInput)->format('Y-m-d'));
            $dateTo = $toHasTime
                ? Carbon::parse($dateToInput)
                : BusinessTime::endOfBusinessDay(Carbon::parse($dateToInput)->format('Y-m-d'));
        } else {
            $businessDate = BusinessTime::currentBusinessDate()->format('Y-m-d');
            $dateFrom = BusinessTime::startOfBusinessDay($businessDate);
            $dateTo = $dateFrom->copy()->addDay();
        }

        $dateFromDisplay = $dateFrom->copy();
        $dateToDisplay = $dateTo->copy();

        // Get statistics for the selected date range
        $confirmedStatuses = ['approved', 'completed'];

        $sites = Site::orderBy('name')->get();
        $financeGroupModels = FinanceGroup::orderBy('name')->get();

        $periodDeposits = 0.0;
        $periodWithdrawals = 0.0;
        $periodDepositCount = 0;
        $periodWithdrawalCount = 0;
        $autoDepositCount = 0;
        $manualDepositCount = 0;

        $financeGroupsMap = [];
        foreach ($financeGroupModels as $group) {
            $financeGroupsMap[$group->id] = [
                'id' => $group->id,
                'name' => $group->name,
                'is_active' => $group->is_active,
                'badge_color' => $group->badge_color,
                'deposits' => 0.0,
                'withdrawals' => 0.0,
                'deposit_count' => 0,
                'withdrawal_count' => 0,
                'kasa_farki' => 0.0,
            ];
        }

        $siteStatsMap = [];
        foreach ($sites as $site) {
            $siteStatsMap[$site->id] = [
                'id' => $site->id,
                'name' => $site->name,
                'is_active' => $site->is_active,
                'deposits' => 0.0,
                'withdrawals' => 0.0,
                'deposit_count' => 0,
                'withdrawal_count' => 0,
                'auto_deposit_count' => 0,
                'manual_deposit_count' => 0,
                'kasa_farki' => 0.0,
            ];
        }

        $siteFinanceStats = [];
        foreach ($sites as $site) {
            foreach ($financeGroupModels as $group) {
                $siteFinanceStats[$site->id][$group->id] = [
                    'deposits' => 0.0,
                    'withdrawals' => 0.0,
                    'deposit_count' => 0,
                    'withdrawal_count' => 0,
                    'kasa_farki' => 0.0,
                ];
            }
        }

        $transactions = Transaction::whereBetween('created_at', [$dateFrom, $dateTo])
            ->whereIn('status', $confirmedStatuses)
            ->get([
                'id',
                'type',
                'source',
                'amount',
                'finance_group_id',
                'site_id',
                'sid',
                'api_key',
            ]);

        foreach ($transactions as $transaction) {
            $amount = (float) $transaction->amount;
            $isDeposit = $transaction->type === 'deposit';
            $isWithdrawal = $transaction->type === 'withdrawal';

            if ($isDeposit) {
                $periodDeposits += $amount;
                $periodDepositCount++;
                if ($transaction->source === 'manual') {
                    $manualDepositCount++;
                } else {
                    $autoDepositCount++;
                }
            } elseif ($isWithdrawal) {
                $periodWithdrawals += $amount;
                $periodWithdrawalCount++;
            }

            $groupId = $transaction->finance_group_id ? (int) $transaction->finance_group_id : null;
            if ($groupId && isset($financeGroupsMap[$groupId])) {
                if ($isDeposit) {
                    $financeGroupsMap[$groupId]['deposits'] += $amount;
                    $financeGroupsMap[$groupId]['deposit_count']++;
                } elseif ($isWithdrawal) {
                    $financeGroupsMap[$groupId]['withdrawals'] += $amount;
                    $financeGroupsMap[$groupId]['withdrawal_count']++;
                }
            }

            $resolvedSite = SiteCredentialResolver::resolveForTransaction($transaction, $sites);
            if (!$resolvedSite) {
                continue;
            }

            $siteId = (int) $resolvedSite->id;
            if (!isset($siteStatsMap[$siteId])) {
                continue;
            }

            if ($isDeposit) {
                $siteStatsMap[$siteId]['deposits'] += $amount;
                $siteStatsMap[$siteId]['deposit_count']++;
                if ($transaction->source === 'manual') {
                    $siteStatsMap[$siteId]['manual_deposit_count']++;
                } else {
                    $siteStatsMap[$siteId]['auto_deposit_count']++;
                }
            } elseif ($isWithdrawal) {
                $siteStatsMap[$siteId]['withdrawals'] += $amount;
                $siteStatsMap[$siteId]['withdrawal_count']++;
            }

            if ($groupId && isset($siteFinanceStats[$siteId][$groupId])) {
                if ($isDeposit) {
                    $siteFinanceStats[$siteId][$groupId]['deposits'] += $amount;
                    $siteFinanceStats[$siteId][$groupId]['deposit_count']++;
                } elseif ($isWithdrawal) {
                    $siteFinanceStats[$siteId][$groupId]['withdrawals'] += $amount;
                    $siteFinanceStats[$siteId][$groupId]['withdrawal_count']++;
                }
            }
        }

        foreach ($financeGroupsMap as $groupId => $groupStats) {
            $financeGroupsMap[$groupId]['kasa_farki'] = $groupStats['deposits'] - $groupStats['withdrawals'];
        }

        foreach ($siteStatsMap as $siteId => $siteStats) {
            $siteStatsMap[$siteId]['kasa_farki'] = $siteStats['deposits'] - $siteStats['withdrawals'];
        }

        foreach ($siteFinanceStats as $siteId => $groupStatsBySite) {
            foreach ($groupStatsBySite as $groupId => $stats) {
                $siteFinanceStats[$siteId][$groupId]['kasa_farki'] = $stats['deposits'] - $stats['withdrawals'];
            }
        }

        $financeGroups = collect(array_values($financeGroupsMap));
        $siteStats = collect(array_values($siteStatsMap));
        $siteStatsById = collect($siteStatsMap);

        return view('backoffice.dashboard', compact(
            'user',
            'periodDeposits',
            'periodWithdrawals',
            'periodDepositCount',
            'periodWithdrawalCount',
            'autoDepositCount',
            'manualDepositCount',
            'financeGroups',
            'sites',
            'siteStats',
            'siteStatsById',
            'siteFinanceStats',
            'dateFromDisplay',
            'dateToDisplay'
        ));
    }
}
