<?php

namespace App\Http\Controllers;

use App\Models\InspectionCollection;
use App\Models\InspectionWorkspace;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class WorkspaceController extends Controller
{
    public function index(Request $request): View
    {
        $workspaces = InspectionWorkspace::query()
            ->where('user_id', $request->user()->id)
            ->with(['collections' => fn ($query) => $query
                ->withCount('inspections')
                ->withSum('inspections', 'estimated_cost')
                ->orderBy('property_name')
                ->orderBy('room_name')])
            ->withCount('collections')
            ->orderBy('name')
            ->get()
            ->map(function (InspectionWorkspace $workspace) {
                $workspace->inspections_count = $workspace->collections->sum('inspections_count');
                $workspace->estimated_cost_sum = $workspace->collections->sum('inspections_sum_estimated_cost');

                return $workspace;
            });

        $collections = $workspaces
            ->flatMap(fn (InspectionWorkspace $workspace) => $workspace->collections)
            ->sortBy(fn (InspectionCollection $collection) => $collection->displayName())
            ->values();

        return view('workspaces.index', [
            'workspaces' => $workspaces,
            'collections' => $collections,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'description' => ['nullable', 'string', 'max:1000'],
            'default_currency' => ['nullable', 'in:IDR,USD'],
        ]);

        InspectionWorkspace::query()->firstOrCreate(
            [
                'user_id' => $request->user()->id,
                'name' => trim($validated['name']),
            ],
            [
                'description' => $validated['description'] ?? null,
                'default_currency' => $validated['default_currency'] ?? 'IDR',
                'metadata' => ['created_from' => 'workspace_page'],
            ]
        );

        return back()->with('status', __('Workspace saved.'));
    }

    public function update(Request $request, InspectionWorkspace $workspace): RedirectResponse
    {
        abort_unless($workspace->user_id === $request->user()->id, 403);

        $validated = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'description' => ['nullable', 'string', 'max:1000'],
            'default_currency' => ['required', 'in:IDR,USD'],
        ]);

        $workspace->forceFill([
            'name' => trim($validated['name']),
            'description' => $validated['description'] ?? null,
            'default_currency' => $validated['default_currency'],
        ])->save();

        return back()->with('status', __('Workspace updated.'));
    }

    public function moveCollection(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'collection_id' => ['required', 'integer', 'exists:inspection_collections,id'],
            'workspace_id' => ['required', 'integer', 'exists:inspection_workspaces,id'],
        ]);

        $workspace = InspectionWorkspace::query()
            ->where('user_id', $request->user()->id)
            ->findOrFail($validated['workspace_id']);

        $collection = InspectionCollection::query()
            ->where('user_id', $request->user()->id)
            ->findOrFail($validated['collection_id']);

        $collection->forceFill([
            'inspection_workspace_id' => $workspace->id,
        ])->save();

        return back()->with('status', __('Collection moved.'));
    }

    public function destroy(InspectionWorkspace $workspace, Request $request): RedirectResponse
    {
        abort_unless($workspace->user_id === $request->user()->id, 403);

        DB::transaction(function () use ($workspace) {
            $workspace->collections()->delete();
            $workspace->delete();
        });

        return back()->with('status', __('Workspace deleted.'));
    }

    public function destroyCollection(InspectionCollection $collection, Request $request): RedirectResponse
    {
        abort_unless($collection->user_id === $request->user()->id, 403);

        $collection->delete();

        return back()->with('status', __('Collection deleted.'));
    }
}
