<?php

namespace Modules\TransactionManagement\Http\Controllers\Web\New\Admin\Report;

use App\Http\Controllers\BaseController;
use App\Http\Controllers\Controller;
use App\Service\BaseServiceInterface;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\View\View;
use Modules\TripManagement\Service\Interface\TripRequestServiceInterface;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ReportController extends BaseController
{
    use AuthorizesRequests;
    protected $tripRequestService;

    public function __construct(TripRequestServiceInterface $tripRequestService)
    {
        parent::__construct($tripRequestService);
        $this->tripRequestService = $tripRequestService;
    }

    public function index(?Request $request, string $type = null): View|Collection|LengthAwarePaginator|null|callable|RedirectResponse
    {
        return parent::index($request, $type); // TODO: Change the autogenerated stub
    }

    public function earningReport(Request $request): View|Collection|LengthAwarePaginator
    {
        $this->authorize('transaction_view');
        $criteria = [
            'payment_status' => PAID
        ];
        if ($request->has('search')) {
            $criteria = array_merge($criteria, [
                'search' => $request->get('search')
            ]);
        }
        $whereHasRelations = [];

        // Add criteria for the `fee` relationship to filter by `cancelled_by` being either `null` or `CUSTOMER`
        $whereHasRelations['fee'] = function ($query) {
            $query->whereNull('cancelled_by')
                ->orWhere('cancelled_by', '=', 'CUSTOMER'); // Handle `null` or `CUSTOMER`
        };
        $trips = $this->tripRequestService->index(criteria: $criteria, relations: ['zone', 'fee'], whereHasRelations: $whereHasRelations, orderBy: ['created_at' => 'desc'], limit: paginationLimit(), offset: $request['page'] ?? 1);
        return view('transactionmanagement::admin.reports.earning', compact('trips'));
    }

    public function singleEarningReportexport(int|string $id)
    {
        $this->authorize('transaction_export');
        $trip = $this->tripRequestService->findOne(id: $id, relations: ['zone', 'fee']);
        return exportData($trip, 'pdf', 'transactionmanagement::admin.reports.single-earning-invoice');

    }

    public function earningReportExport(Request $request): \Illuminate\Contracts\View\View|Factory|Response|StreamedResponse|string|Application
    {
        $this->authorize('transaction_export');

        $criteria = [
            'payment_status' => PAID
        ];
        $whereHasRelations = [];

        // Add criteria for the `fee` relationship to filter by `cancelled_by` being either `null` or `CUSTOMER`
        $whereHasRelations['fee'] = function ($query) {
            $query->whereNull('cancelled_by')
                ->orWhere('cancelled_by', '=', 'CUSTOMER'); // Handle `null` or `CUSTOMER`
        };
        if ($request->has('search')) {
            $criteria = array_merge($criteria, [
                'search' => $request->get('search')
            ]);
        }
        $trips = $this->tripRequestService->index(criteria: $criteria, relations: ['zone', 'fee'],whereHasRelations: $whereHasRelations, orderBy: ['created_at' => 'desc']);
        $data = $trips->map(fn($item) => [
            'id' => $item['id'],
            'Trip ID' => $item['ref_id'],
            'Date' => date('d F Y', strtotime($item['created_at'])) . ' ' . date('h:i a', strtotime($item['created_at'])),
            'Zone' => $item['zone']?->name,
            'Trip Type' => ucwords($item['type'] . ($item['ride_request_type'] == SCHEDULED ? ' (' . SCHEDULED . ')' : '')),
            'Total Trip Cost' => getCurrencyFormat($item['paid_fare']),
            'Admin Commission' => getCurrencyFormat($item['fee'] ? ($item['fee']->admin_commission - $item['fee']->vat_tax) : 0),
            'Tax Collected' => getCurrencyFormat($item['fee'] ? $item['fee']->vat_tax : 0),
            'Earning' => getCurrencyFormat($item['fee'] ? $item['fee']->admin_commission : 0),
        ]);
        return exportData($data, 'excel', 'null');
    }


    public function expenseReport(Request $request): View|Collection|LengthAwarePaginator
    {
        $this->authorize('transaction_view');
        $criteria = [
            'payment_status' => PAID
        ];
        $whereHasRelations = [];

        // Add criteria for the `fee` relationship to filter by `cancelled_by` being either `null` or `CUSTOMER`
        $whereHasRelations['fee'] = function ($query) {
            $query->whereNull('cancelled_by')
                ->orWhere('cancelled_by', '=', 'CUSTOMER'); // Handle `null` or `CUSTOMER`
        };
        if ($request->has('search')) {
            $criteria = array_merge($criteria, [
                'search' => $request->get('search')
            ]);
        }
        $trips = $this->tripRequestService->index(criteria: $criteria, relations: ['zone', 'fee'],whereHasRelations: $whereHasRelations, orderBy: ['created_at' => 'desc'], limit: paginationLimit(), offset: $request['page'] ?? 1);
        return view('transactionmanagement::admin.reports.expense', compact('trips'));
    }

    public function expenseReportExport(Request $request): \Illuminate\Contracts\View\View|Factory|Response|StreamedResponse|string|Application
    {
        $this->authorize('transaction_export');

        $criteria = [
            'payment_status' => PAID
        ];
        $whereHasRelations = [];

        // Add criteria for the `fee` relationship to filter by `cancelled_by` being either `null` or `CUSTOMER`
        $whereHasRelations['fee'] = function ($query) {
            $query->whereNull('cancelled_by')
                ->orWhere('cancelled_by', '=', 'CUSTOMER'); // Handle `null` or `CUSTOMER`
        };
        if ($request->has('search')) {
            $criteria = array_merge($criteria, [
                'search' => $request->get('search')
            ]);
        }
        $trips = $this->tripRequestService->index(criteria: $criteria, relations: ['zone', 'fee'],whereHasRelations: $whereHasRelations, orderBy: ['created_at' => 'desc']);
        $data = $trips->map(fn($item) => [
            'id' => $item['id'],
            'Trip ID' => $item['ref_id'],
            'Date' => date('d F Y', strtotime($item['created_at'])) . ' ' . date('h:i a', strtotime($item['created_at'])),
            'Zone' => $item['zone']?->name,
            'Trip Type' => ucwords($item['type'] . ($item['ride_request_type'] == SCHEDULED ? ' (' . SCHEDULED . ')' : '')),
            'Total Trip Cost' => getCurrencyFormat($item['paid_fare']),
            'Coupon Amount' => getCurrencyFormat($item['coupon_amount']),
            'Discount Amount' => getCurrencyFormat($item['discount_amount']),
            'Total Expense' => getCurrencyFormat($item['discount_amount'] + $item['coupon_amount'])
        ]);
        return exportData($data, 'excel', '');
    }

    public function singleExpenseReportexport(int|string $id)
    {
        $this->authorize('transaction_export');
        $trip = $this->tripRequestService->findOne(id: $id, relations: ['zone', 'fee']);
        return exportData($trip, 'pdf', 'transactionmanagement::admin.reports.single-expense-invoice');
    }

    public function dateRideTypeWiseEarningStatistics(Request $request)
    {
        $data = $this->tripRequestService->getDateRideTypeWiseEarningStatistics($request->all());
        return response()->json($data);
    }

    public function dateZoneWiseEarningStatistics(Request $request)
    {
        $data = $this->tripRequestService->getDateZoneWiseEarningStatistics($request->all());
        return response()->json($data);
    }

    public function dateRideTypeWiseExpenseStatistics(Request $request)
    {
        $data = $this->tripRequestService->getDateRideTypeWiseExpenseStatistics($request->all());
        return response()->json($data);
    }

    public function dateZoneWiseExpenseStatistics(Request $request)
    {
        $data = $this->tripRequestService->getDateZoneWiseExpenseStatistics($request->all());
        return response()->json($data);
    }
}
