<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\UpdateStaffWorkingHoursRequest;
use App\Models\StaffBreak;
use App\Models\StaffProfile;
use App\Services\Tenancy\CurrentBusiness;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Carbon;
use Illuminate\View\View;

class StaffWorkingHoursController extends Controller
{
    public function edit(StaffProfile $staff, CurrentBusiness $currentBusiness): View
    {
        $business = $this->authorizeStaff($staff, $currentBusiness);
        $staff->load(['services', 'workingHours', 'breaks']);

        return view('admin.staff.working-hours', [
            'staff' => $staff,
            'hours' => $this->hourRows($staff),
            'summary' => [
                'weekly_hours' => $staff->workingHours->where('is_closed', false)->sum(function ($row): float {
                    if (! $row->starts_at || ! $row->ends_at) {
                        return 0;
                    }

                    return Carbon::parse($row->starts_at)->diffInMinutes(Carbon::parse($row->ends_at)) / 60;
                }),
                'working_days' => $staff->workingHours->where('is_closed', false)->count(),
                'breaks' => $staff->breaks->count(),
            ],
            'business' => $business,
        ]);
    }

    public function update(UpdateStaffWorkingHoursRequest $request, StaffProfile $staff, CurrentBusiness $currentBusiness): RedirectResponse
    {
        $business = $this->authorizeStaff($staff, $currentBusiness);
        $hours = collect($request->validated('hours'));

        foreach ($hours as $row) {
            $enabled = (bool) ($row['enabled'] ?? false);

            $staff->workingHours()->updateOrCreate(
                ['day_of_week' => $row['day_of_week']],
                [
                    'business_id' => $business->id,
                    'starts_at' => $enabled ? ($row['starts_at'] ?? null) : null,
                    'ends_at' => $enabled ? ($row['ends_at'] ?? null) : null,
                    'is_closed' => ! $enabled,
                ]
            );
        }

        StaffBreak::query()
            ->where('business_id', $business->id)
            ->where('staff_profile_id', $staff->id)
            ->whereNull('date')
            ->where('is_recurring', true)
            ->delete();

        foreach ($hours as $row) {
            if (! ($row['enabled'] ?? false) || empty($row['break_start']) || empty($row['break_end'])) {
                continue;
            }

            StaffBreak::query()->create([
                'business_id' => $business->id,
                'staff_profile_id' => $staff->id,
                'title' => 'Break',
                'day_of_week' => $row['day_of_week'],
                'starts_at' => $row['break_start'],
                'ends_at' => $row['break_end'],
                'is_recurring' => true,
            ]);
        }

        return redirect()
            ->route('admin.staff.working-hours', $staff)
            ->with('status', 'Working hours updated successfully.');
    }

    private function authorizeStaff(StaffProfile $staff, CurrentBusiness $currentBusiness)
    {
        $business = $currentBusiness->get() ?? abort(403);

        abort_unless((int) $staff->business_id === (int) $business->id, 404);

        return $business;
    }

    private function hourRows(StaffProfile $staff): array
    {
        $workingHours = $staff->workingHours->keyBy('day_of_week');
        $breaks = $staff->breaks
            ->where('is_recurring', true)
            ->whereNull('date')
            ->keyBy('day_of_week');
        $days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

        return collect(range(0, 6))->map(function (int $day) use ($days, $workingHours, $breaks): array {
            $hour = $workingHours->get($day);
            $break = $breaks->get($day);

            return [
                'day_of_week' => $day,
                'day' => $days[$day],
                'enabled' => $hour ? ! $hour->is_closed : $day !== 0,
                'start' => $hour?->starts_at ? substr((string) $hour->starts_at, 0, 5) : ($day === 0 ? '' : '09:00'),
                'end' => $hour?->ends_at ? substr((string) $hour->ends_at, 0, 5) : ($day === 0 ? '' : '17:00'),
                'break_start' => $break?->starts_at ? substr((string) $break->starts_at, 0, 5) : '',
                'break_end' => $break?->ends_at ? substr((string) $break->ends_at, 0, 5) : '',
            ];
        })->all();
    }
}
