<?php

namespace App\Http\Controllers\Owner;

use App\Http\Controllers\Controller;
use App\Models\ArtistItem;
use App\Models\GiftItem;
use App\Models\OtherCostItem;
use App\Models\Serenata;
use App\Models\SerenataPayment;
use App\Support\OwnerWorkspace;
use Carbon\Carbon;
use Illuminate\Http\Request;

class ReportController extends Controller
{
    private const PLANNED_PAYMENT_PREFIX = '[PLAN]';

    public function index(Request $request)
    {
        $organizationId = (int) ($request->user()->organization_id ?? 0);
        abort_if($organizationId <= 0, 403);

        $dateFrom = trim((string) $request->query('date_from', Carbon::today()->startOfMonth()->toDateString()));
        $dateTo = trim((string) $request->query('date_to', Carbon::today()->toDateString()));

        try {
            $from = Carbon::parse($dateFrom)->startOfDay();
        } catch (\Throwable) {
            $from = Carbon::today()->startOfMonth();
        }

        try {
            $to = Carbon::parse($dateTo)->endOfDay();
        } catch (\Throwable) {
            $to = Carbon::today()->endOfDay();
        }

        if ($from->gt($to)) {
            [$from, $to] = [$to->copy()->startOfDay(), $from->copy()->endOfDay()];
        }

        $serenataQuery = OwnerWorkspace::applyScope(
            Serenata::query()
                ->where('organization_id', $organizationId)
                ->whereBetween('event_date', [$from->toDateString(), $to->toDateString()]),
            $request
        );

        $serenatas = (clone $serenataQuery)
            ->get([
                'id',
                'code',
                'event_date',
                'service_status',
                'payment_status',
                'total_charged',
                'discount_amount',
                'gift_amount',
                'artist_amount',
                'other_cost_amount',
                'gift_items',
                'artist_items',
                'other_cost_items',
            ]);

        $giftCostMap = GiftItem::query()
            ->where('organization_id', $organizationId)
            ->pluck('internal_cost', 'code');

        $artistCostMap = ArtistItem::query()
            ->where('organization_id', $organizationId)
            ->pluck('internal_cost', 'code');

        $otherCostMap = OtherCostItem::query()
            ->where('organization_id', $organizationId)
            ->pluck('internal_cost', 'code');

        $estimatedGiftCost = 0.0;
        $estimatedArtistCost = 0.0;
        $estimatedOtherCost = 0.0;

        foreach ($serenatas as $serenata) {
            foreach ((array) ($serenata->gift_items ?? []) as $item) {
                if ((bool) data_get($item, 'is_deleted', false)) {
                    continue;
                }
                $code = (string) data_get($item, 'code', '');
                $qty = max(1, (int) data_get($item, 'quantity', 1));
                $unit = (float) ($giftCostMap[$code] ?? 0);
                $estimatedGiftCost += $unit * $qty;
            }

            foreach ((array) ($serenata->artist_items ?? []) as $item) {
                if ((bool) data_get($item, 'is_deleted', false)) {
                    continue;
                }
                $code = (string) data_get($item, 'code', '');
                $qty = max(1, (int) data_get($item, 'quantity', 1));
                $unit = (float) ($artistCostMap[$code] ?? 0);
                $estimatedArtistCost += $unit * $qty;
            }

            foreach ((array) ($serenata->other_cost_items ?? []) as $item) {
                if ((bool) data_get($item, 'is_deleted', false)) {
                    continue;
                }
                $code = (string) data_get($item, 'code', '');
                $qty = max(1, (int) data_get($item, 'quantity', 1));
                $unit = (float) ($otherCostMap[$code] ?? 0);
                $estimatedOtherCost += $unit * $qty;
            }
        }

        $salesTotal = (float) $serenatas->sum('total_charged');
        $discountTotal = (float) $serenatas->sum('discount_amount');
        $internalCostEstimated = (float) ($estimatedGiftCost + $estimatedArtistCost + $estimatedOtherCost);
        $grossProfitEstimated = $salesTotal - $internalCostEstimated;

        $paymentQuery = SerenataPayment::query()
            ->where('organization_id', $organizationId)
            ->whereBetween('paid_at', [$from->toDateTimeString(), $to->toDateTimeString()])
            ->where(function ($query) {
                $query->whereNull('note')
                    ->orWhere('note', 'not like', self::PLANNED_PAYMENT_PREFIX . '%');
            });

        $paymentQuery->whereHas('serenata', function ($query) use ($request) {
            OwnerWorkspace::applyScope($query, $request);
        });

        $paymentsTotal = (float) (clone $paymentQuery)->sum('amount');

        $recentPayments = (clone $paymentQuery)
            ->with(['registeredBy:id,name', 'method:id,name', 'serenata:id,code'])
            ->latest('paid_at')
            ->limit(20)
            ->get();

        $pendingToCollect = max(0, $salesTotal - $paymentsTotal);

        $statusSummary = $serenatas
            ->groupBy('service_status')
            ->map(fn ($rows) => [
                'count' => $rows->count(),
                'sales' => (float) $rows->sum('total_charged'),
            ])
            ->sortKeys();

        return view('content.owner.reports.index', [
            'filters' => [
                'date_from' => $from->toDateString(),
                'date_to' => $to->toDateString(),
            ],
            'summary' => [
                'services' => $serenatas->count(),
                'sales_total' => $salesTotal,
                'payments_total' => $paymentsTotal,
                'pending_to_collect' => $pendingToCollect,
                'discount_total' => $discountTotal,
                'internal_cost_estimated' => $internalCostEstimated,
                'gross_profit_estimated' => $grossProfitEstimated,
                'estimated_gift_cost' => $estimatedGiftCost,
                'estimated_artist_cost' => $estimatedArtistCost,
                'estimated_other_cost' => $estimatedOtherCost,
            ],
            'statusSummary' => $statusSummary,
            'recentPayments' => $recentPayments,
        ]);
    }
}
