<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class DriverTransactionController extends Controller
{
    public function index(Request $request)
    {
        // Authenticate driver
        $user = Auth::user();

        if (!$user || $user->role !== 'driver') {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $now = Carbon::now();
        $filterType = $request->query('filter_type', 'daily');
        $dataType = $request->query('data_type', null);

        // Define date ranges
        $todayStart = $now->copy()->startOfDay();
        $yesterdayStart = $now->copy()->subDay()->startOfDay();
        $pastWeekStart = $now->copy()->subDays(7)->startOfDay();
        $last30DaysStart = $now->copy()->subDays(30)->startOfDay();
        $pastYearStart = $now->copy()->subYear()->startOfDay();

        // Fetch data
        $cashCollectionHistory = DB::select('
            SELECT id, delivery_agent_id, order_id, amount, transaction_date, created_at, updated_at 
            FROM cash_collection_history 
            WHERE delivery_agent_id = ?', [$user->user_id]
        );

        $cashCollections = DB::select('
            SELECT id, delivery_agent_id, amount_collected, date_of_submission, recipient, created_at, updated_at 
            FROM cash_collections 
            WHERE delivery_agent_id = ?', [$user->user_id]
        );

        $referralPoints = DB::select('
            SELECT id, referrer_id, referred_id, points, created_at, updated_at 
            FROM referral_points 
            WHERE referrer_id = ?', [$user->id]
        );

        $driverIncentives = DB::select('
            SELECT id, driver_id, order_id, amount, created_at, updated_at 
            FROM driver_incentives 
            WHERE driver_id = ?', [$user->user_id]
        );

        // Initialize response
        $totalEarnings = 0; // Initialize total earnings
        $earningsData = []; // Initialize earnings data
        $totalLedger = 0; // Initialize total ledger
        $response = []; // Initialize response

        if ($dataType === 'earnings') {
            // Filter earnings
            $filteredEarnings = array_merge(
                $this->filterByType($driverIncentives, $filterType, $todayStart, $yesterdayStart, $pastWeekStart, $last30DaysStart, $pastYearStart, $now, 'created_at'),
                $this->filterByType($referralPoints, $filterType, $todayStart, $yesterdayStart, $pastWeekStart, $last30DaysStart, $pastYearStart, $now, 'created_at')
            );

            foreach ($filteredEarnings as $item) {
                $amount = isset($item->points) ? $item->points : $item->amount;
                $totalEarnings += $amount;

                $dateKey = Carbon::parse($item->created_at)->format('M d, Y');

                if (!isset($earningsData[$dateKey])) {
                    $earningsData[$dateKey] = [
                        'date' => $dateKey,
                        'total_earning' => 0,
                        'earning' => []
                    ];
                }

                $earningsData[$dateKey]['total_earning'] += $amount;
                $earningsData[$dateKey]['earning'][] = $item;
            }

            $response['total_earning'] = $totalEarnings; // Total earnings at the top
            $response['earnings'] = array_values($earningsData); // Convert associative array to indexed array
        } elseif ($dataType === 'ledger') {
            // Filter ledger
            $filteredLedger = array_merge(
                $this->filterByType($cashCollectionHistory, $filterType, $todayStart, $yesterdayStart, $pastWeekStart, $last30DaysStart, $pastYearStart, $now, 'transaction_date'),
                $this->filterByType($cashCollections, $filterType, $todayStart, $yesterdayStart, $pastWeekStart, $last30DaysStart, $pastYearStart, $now, 'date_of_submission')
            );

            foreach ($filteredLedger as $item) {
                $amount = isset($item->amount_collected) ? $item->amount_collected : $item->amount;
                $totalLedger += $amount;

                $dateKey = Carbon::parse($item->transaction_date ?? $item->date_of_submission)->format('M d, Y');
                if (!isset($response['ledger'][$dateKey])) {
                    $response['ledger'][$dateKey] = [
                        'total_ledger' => 0,
                        'date' => $dateKey,
                        'ledger' => []
                    ];
                }
                $response['ledger'][$dateKey]['total_ledger'] += $amount;
                $response['ledger'][$dateKey]['ledger'][] = $item;
            }

            $response['total_ledger'] = $totalLedger;
        }

        return response()->json($response);
    }

    private function filterByType(array $data, $filterType, Carbon $todayStart, Carbon $yesterdayStart, Carbon $pastWeekStart, Carbon $last30DaysStart, Carbon $pastYearStart, Carbon $now, $dateField)
    {
        switch ($filterType) {
            case 'daily':
                return $this->filterByDateRange($data, $todayStart, $now, $dateField);
            case 'yesterday':
                return $this->filterByDateRange($data, $yesterdayStart, $todayStart, $dateField);
            case 'weekly':
                return $this->filterByDateRange($data, $pastWeekStart, $now, $dateField);
            case 'monthly':
                return $this->filterByDateRange($data, $last30DaysStart, $now, $dateField);
            case 'yearly':
                return $this->filterByDateRange($data, $pastYearStart, $now, $dateField);
            default:
                return $data;
        }
    }

    private function filterByDateRange(array $data, Carbon $start, Carbon $end, $dateField)
    {
        return array_filter($data, function ($item) use ($start, $end, $dateField) {
            $date = Carbon::parse($item->$dateField);
            return $date->between($start, $end);
        });
    }
}
