<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\CloseDayLedgerRequest;
use App\Http\Requests\Admin\DayLedgerFilterRequest;
use App\Http\Requests\Admin\ReopenDayLedgerRequest;
use App\Http\Requests\Admin\StoreLedgerEntryRequest;
use App\Services\LedgerService;
use App\Services\LocationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
use Barryvdh\DomPDF\Facade\Pdf;

class LedgerController extends Controller
{
    public function __construct(
        private readonly LedgerService $ledgerService,
        private readonly LocationService $locationService
    ) {
    }

    public function index(DayLedgerFilterRequest $request): View
    {
        $validated = $request->validated();
        $user = Auth::user();
        $locationId = $this->locationService->resolveAuthorizedFilterLocationId(
            $user,
            $validated['location_id'] ?? null
        );
        $overview = $this->ledgerService->getOverview(
            $validated['date'],
            $validated['payment_mode'] ?? null,
            $validated['order_type'] ?? LedgerService::ORDER_TYPE_ALL,
            $locationId
        );

        return view('admin.reports.day-ledger', [
            'overview' => $overview,
            'paymentModes' => LedgerService::PAYMENT_MODES,
            'paymentModeLabels' => LedgerService::PAYMENT_MODE_LABELS,
            'orderTypes' => [
                LedgerService::ORDER_TYPE_ALL => 'All',
                LedgerService::ORDER_TYPE_POS => 'POS',
                LedgerService::ORDER_TYPE_ONLINE => 'Online',
            ],
            'locations' => $this->locationService->accessibleLocations($user),
            'locationId' => $locationId,
            'canViewAllShops' => $this->locationService->userCanViewAllLocations($user),
        ]);
    }

    public function storeEntry(StoreLedgerEntryRequest $request): RedirectResponse
    {
        $validated = $request->validated();
        $locationId = $this->locationService->resolveAuthorizedFilterLocationId(
            Auth::user(),
            $validated['location_id'] ?? $request->input('location_id')
        );

        $this->ledgerService->createManualEntry([
            ...$validated,
            'location_id' => $locationId,
            'created_by' => Auth::id(),
            'reference_type' => $validated['reference_type'] ?? 'manual',
        ]);

        return redirect()
            ->route('admin.reports.day-ledger', array_filter([
                'date' => $validated['ledger_date'],
                'location_id' => $locationId,
            ]))
            ->with('success', 'Manual ledger entry added successfully.');
    }

    public function closeDay(CloseDayLedgerRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        $locationId = $this->locationService->resolveAuthorizedFilterLocationId(
            Auth::user(),
            $request->input('location_id')
        );

        $this->ledgerService->closeDay(
            $validated['date'],
            (int) Auth::id(),
            isset($validated['opening_balance']) ? (float) $validated['opening_balance'] : null,
            $locationId
        );

        return redirect()
            ->route('admin.reports.day-ledger', array_filter([
                'date' => $validated['date'],
                'location_id' => $locationId,
            ]))
            ->with('success', 'Day closed successfully.');
    }

    public function reopenDay(ReopenDayLedgerRequest $request): RedirectResponse
    {
        $validated = $request->validated();
        $user = Auth::user();
        $locationId = $this->locationService->resolveAuthorizedFilterLocationId(
            $user,
            $request->input('location_id')
        );

        $this->ledgerService->reopenDay(
            $validated['date'],
            $this->isSuperAdmin((int) $user->id),
            $locationId
        );

        return redirect()
            ->route('admin.reports.day-ledger', array_filter([
                'date' => $validated['date'],
                'location_id' => $locationId,
            ]))
            ->with('success', 'Day reopened successfully.');
    }

    public function exportPdf(DayLedgerFilterRequest $request)
    {
        $validated = $request->validated();
        $locationId = $this->locationService->resolveAuthorizedFilterLocationId(
            Auth::user(),
            $validated['location_id'] ?? null
        );
        $overview = $this->ledgerService->getOverview(
            $validated['date'],
            $validated['payment_mode'] ?? null,
            $validated['order_type'] ?? LedgerService::ORDER_TYPE_ALL,
            $locationId
        );

        $pdf = Pdf::loadView('admin.reports.day-ledger-pdf', [
            'overview' => $overview,
        ]);

        return $pdf->download('day-ledger-' . $overview['date'] . '.pdf');
    }

    public function monthlySummary(Request $request): View
    {
        $user = Auth::user();
        if (!$user || (($user->user_type ?? null) !== 'admin')) {
            abort(403);
        }

        $request->validate([
            'month' => ['required', 'date_format:Y-m'],
        ]);

        $month = $request->input('month');
        $rows = $this->ledgerService->aggregateMonthly($month);

        return view('admin.reports.day-ledger-monthly', [
            'month' => $month,
            'rows' => $rows,
        ]);
    }

    public function paymentModeSummary(DayLedgerFilterRequest $request): View
    {
        $validated = $request->validated();
        $rows = $this->ledgerService->aggregatePaymentModes(
            $validated['date'],
            $validated['order_type'] ?? LedgerService::ORDER_TYPE_ALL
        );

        return view('admin.reports.day-ledger-payment-summary', [
            'date' => $validated['date'],
            'rows' => $rows,
            'orderType' => $validated['order_type'] ?? LedgerService::ORDER_TYPE_ALL,
            'paymentModeLabels' => LedgerService::PAYMENT_MODE_LABELS,
        ]);
    }

    private function isSuperAdmin(int $userId): bool
    {
        $isSuperAdmin = DB::table('model_has_roles')
            ->join('roles', 'roles.id', '=', 'model_has_roles.role_id')
            ->where('model_has_roles.model_id', $userId)
            ->where('model_has_roles.model_type', \App\Models\User::class)
            ->where('roles.name', 'super_admin')
            ->exists();

        if ($isSuperAdmin) {
            return true;
        }

        $superAdminAssigned = DB::table('model_has_roles')
            ->join('roles', 'roles.id', '=', 'model_has_roles.role_id')
            ->where('roles.name', 'super_admin')
            ->exists();

        if ($superAdminAssigned) {
            return false;
        }

        return (($user = \App\Models\User::find($userId)) && ($user->user_type ?? null) === 'admin');
    }
}
