<?php

namespace App\Http\Controllers;

use App\Models\DamageFinding;
use App\Models\Inspection;
use App\Models\InspectionCollection;
use App\Models\InspectionWorkspace;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;

class CostEstimationController extends Controller
{
    public function index(Request $request): View
    {
        $severity = $request->string('severity')->toString();
        $search = trim($request->string('search')->toString());
        $workspace = $this->activeWorkspace($request);
        $workspaceId = (int) $workspace->id;
        $collectionId = $request->integer('collection_id');
        if ($collectionId > 0) {
            $collectionBelongsToWorkspace = InspectionCollection::query()
                ->where('user_id', $request->user()->id)
                ->where('inspection_workspace_id', $workspaceId)
                ->where('id', $collectionId)
                ->exists();

            if (! $collectionBelongsToWorkspace) {
                $collectionId = 0;
            }
        }

        $inspectionQuery = Inspection::query()
            ->whereHas('collection', fn ($query) => $query->where('inspection_workspace_id', $workspaceId));
        if ($collectionId > 0) {
            $inspectionQuery->where('inspection_collection_id', $collectionId);
        }

        $findings = DamageFinding::query()
            ->with('inspection.collection.workspace')
            ->whereHas('inspection.collection', fn ($query) => $query->where('inspection_workspace_id', $workspaceId))
            ->when($collectionId > 0, fn ($query) => $query->whereHas('inspection', fn ($inspectionQuery) => $inspectionQuery->where('inspection_collection_id', $collectionId)))
            ->when($severity !== '', fn ($query) => $query->where('severity', $severity))
            ->when($search !== '', function ($query) use ($search) {
                $query->where(function ($nestedQuery) use ($search) {
                    $nestedQuery
                        ->where('category', 'like', "%{$search}%")
                        ->orWhereHas('inspection', function ($inspectionQuery) use ($search) {
                            $inspectionQuery
                                ->where('property_name', 'like', "%{$search}%")
                                ->orWhere('property_address', 'like', "%{$search}%")
                                ->orWhereHas('collection', function ($collectionQuery) use ($search) {
                                    $collectionQuery
                                        ->where('property_name', 'like', "%{$search}%")
                                        ->orWhere('room_name', 'like', "%{$search}%");
                                });
                        });
                });
            })
            ->orderByDesc('estimated_repair_cost')
            ->paginate(10)
            ->withQueryString();

        $baseFindingQuery = DamageFinding::query()
            ->whereHas('inspection.collection', fn ($query) => $query->where('inspection_workspace_id', $workspaceId))
            ->when($collectionId > 0, fn ($query) => $query->whereHas('inspection', fn ($inspectionQuery) => $inspectionQuery->where('inspection_collection_id', $collectionId)));

        $stats = [
            'inspectionCost' => (clone $inspectionQuery)->sum('estimated_cost'),
            'repairCost' => (clone $baseFindingQuery)->sum('estimated_repair_cost'),
            'highRiskCost' => (clone $baseFindingQuery)->where('severity', 'high')->sum('estimated_repair_cost'),
            'findingCount' => (clone $baseFindingQuery)->count(),
        ];

        $severityBreakdown = DamageFinding::query()
            ->whereHas('inspection.collection', fn ($query) => $query->where('inspection_workspace_id', $workspaceId))
            ->when($collectionId > 0, fn ($query) => $query->whereHas('inspection', fn ($inspectionQuery) => $inspectionQuery->where('inspection_collection_id', $collectionId)))
            ->selectRaw('severity, count(*) as total, sum(estimated_repair_cost) as cost')
            ->groupBy('severity')
            ->get()
            ->keyBy('severity');
        $collections = InspectionCollection::query()
            ->where('user_id', $request->user()->id)
            ->where('inspection_workspace_id', $workspaceId)
            ->withCount('inspections')
            ->orderBy('property_name')
            ->orderBy('room_name')
            ->get();
        $workspaces = InspectionWorkspace::query()
            ->where('user_id', $request->user()->id)
            ->withCount('collections')
            ->orderBy('name')
            ->get()
            ->map(function (InspectionWorkspace $workspace) {
                $workspace->estimated_cost_sum = Inspection::query()
                    ->whereHas('collection', fn ($query) => $query->where('inspection_workspace_id', $workspace->id))
                    ->sum('estimated_cost');

                return $workspace;
            });

        return view('costs.index', [
            'findings' => $findings,
            'stats' => $stats,
            'severityBreakdown' => $severityBreakdown,
            'workspaces' => $workspaces,
            'activeWorkspace' => $workspace,
            'collections' => $collections,
            'filters' => [
                'workspace_id' => $workspaceId,
                'severity' => $severity,
                'search' => $search,
                'collection_id' => $collectionId,
            ],
        ]);
    }

    private function activeWorkspace(Request $request): InspectionWorkspace
    {
        $requestedId = $request->integer('workspace_id');

        if ($requestedId > 0) {
            $workspace = InspectionWorkspace::query()
                ->where('user_id', $request->user()->id)
                ->find($requestedId);

            if ($workspace !== null) {
                return $workspace;
            }
        }

        return InspectionWorkspace::query()->firstOrCreate(
            ['user_id' => $request->user()->id, 'name' => 'Default Workspace'],
            ['default_currency' => 'IDR', 'metadata' => ['created_from' => 'controller']]
        );
    }
}
