<?php

namespace App\Domains\Sale\Controllers\AdminApp;

use App\Domains\Sale\Requests\AdminAppSaleIndexRequest;
use App\Domains\Sale\Requests\AdminAppSaleModificationPdfRequest;
use App\Domains\Sale\Requests\AdminAppSalePdfRequest;
use App\Domains\Sale\Resources\AdminApp\SaleDetailResource;
use App\Domains\Sale\Resources\AdminApp\SaleModificationResource;
use App\Domains\Sale\Resources\AdminApp\SaleResource;
use App\Domains\Sale\Resources\AdminApp\SaleTicketResource;
use App\Domains\Sale\Services\AdminAppSaleExcelService;
use App\Domains\Sale\Services\AdminAppSalePdfService;
use App\Domains\Sale\Services\AdminAppSaleService;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class SaleController extends Controller
{
    public function __construct(
        protected AdminAppSaleService $saleService,
        protected AdminAppSalePdfService $salePdfService,
        protected AdminAppSaleExcelService $saleExcelService,
    ) {}

    public function index(AdminAppSaleIndexRequest $request): AnonymousResourceCollection
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return SaleResource::collection(
            $this->saleService->sales($tenant, $request->validated())
        )->additional([
            'confirmed_sales_total' => $this->saleService->confirmedSalesTotal($tenant),
        ]);
    }

    public function show(Request $request, int $sale): SaleDetailResource
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return new SaleDetailResource($this->saleService->detail($tenant, $sale));
    }

    public function tickets(Request $request, int $sale): AnonymousResourceCollection
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return SaleTicketResource::collection(
            $this->saleService->tickets($tenant, $sale)
        );
    }

    public function confirm(Request $request, int $sale): SaleResource
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return new SaleResource($this->saleService->confirm($tenant, $sale));
    }

    public function cancel(Request $request, int $sale): SaleResource
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return new SaleResource($this->saleService->cancel($tenant, $sale));
    }

    public function modifications(Request $request): AnonymousResourceCollection
    {
        return SaleModificationResource::collection(
            $this->saleService->modifications(
                $request->user()->tenant()->firstOrFail()
            )
        );
    }

    public function downloadPdf(AdminAppSalePdfRequest $request): Response
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return $this->salePdfService->downloadSales(
            $tenant,
            $this->saleService->salesForExport($tenant, $request->validated()),
            $request->validated('timezone'),
        );
    }

    public function downloadModificationsPdf(AdminAppSaleModificationPdfRequest $request): Response
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return $this->salePdfService->downloadModifications(
            $tenant,
            $this->saleService->modificationsForExport($tenant),
            $request->validated('timezone'),
        );
    }

    public function downloadExcel(AdminAppSalePdfRequest $request): StreamedResponse
    {
        $tenant = $request->user()->tenant()->firstOrFail();

        return $this->saleExcelService->downloadSales(
            $tenant,
            $this->saleService->salesForExport($tenant, $request->validated()),
            $request->validated('timezone'),
        );
    }

    public function downloadModificationsExcel(
        AdminAppSaleModificationPdfRequest $request,
    ): StreamedResponse {
        $tenant = $request->user()->tenant()->firstOrFail();

        return $this->saleExcelService->downloadModifications(
            $tenant,
            $this->saleService->modificationsForExport($tenant),
            $request->validated('timezone'),
        );
    }
}
