<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Shift;
use App\Models\User;
use App\Models\UserShift;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ShiftController extends Controller
{
    /**
     * Get all shifts for the company
     */
    public function index(Request $request): JsonResponse
    {
        $user = $request->user();
        $company = $user->company;

        if (!$company) {
            return response()->json([
                'success' => false,
                'message' => 'Perusahaan tidak ditemukan',
            ], 404);
        }

        $shifts = Shift::where('company_id', $company->id)
            ->withCount('users')
            ->orderBy('is_default', 'desc')
            ->orderBy('name')
            ->get()
            ->map(function ($shift) {
                return [
                    'id' => $shift->id,
                    'name' => $shift->name,
                    'code' => $shift->code,
                    'start_time' => $shift->start_time?->format('H:i'),
                    'end_time' => $shift->end_time?->format('H:i'),
                    'duration_minutes' => $shift->duration_minutes,
                    'is_default' => $shift->is_default,
                    'is_active' => $shift->is_active,
                    'users_count' => $shift->users_count,
                ];
            });

        return response()->json([
            'success' => true,
            'data' => $shifts,
            'office_time_enabled' => $company->office_time_enabled ?? false,
        ]);
    }

    /**
     * Get a specific shift
     */
    public function show(Request $request, Shift $shift): JsonResponse
    {
        $user = $request->user();

        if ($shift->company_id !== $user->company_id && !$user->hasRole('super_admin')) {
            return response()->json([
                'success' => false,
                'message' => 'Shift tidak ditemukan',
            ], 404);
        }

        $shift->load(['users' => function ($q) {
            $q->select('users.id', 'users.name', 'users.employee_id', 'users.nip', 'users.department', 'users.position')
              ->withPivot(['effective_date', 'end_date']);
        }]);

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $shift->id,
                'name' => $shift->name,
                'code' => $shift->code,
                'start_time' => $shift->start_time?->format('H:i'),
                'end_time' => $shift->end_time?->format('H:i'),
                'duration_minutes' => $shift->duration_minutes,
                'is_default' => $shift->is_default,
                'is_active' => $shift->is_active,
                'users' => $shift->users->map(function ($user) {
                    return [
                        'id' => $user->id,
                        'name' => $user->name,
                        'employee_id' => $user->employee_id,
                        'nip' => $user->nip,
                        'department' => $user->department,
                        'position' => $user->position,
                        'effective_date' => $user->pivot->effective_date,
                        'end_date' => $user->pivot->end_date,
                    ];
                }),
            ],
        ]);
    }

    /**
     * Create a new shift (admin only)
     */
    public function store(Request $request): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat membuat shift',
            ], 403);
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'code' => 'nullable|string|max:50',
            'start_time' => 'required|date_format:H:i',
            'end_time' => 'required|date_format:H:i',
            'is_default' => 'sometimes|boolean',
            'is_active' => 'sometimes|boolean',
        ]);

        $company = $user->company;

        // If this shift is default, unset other defaults
        if ($validated['is_default'] ?? false) {
            Shift::where('company_id', $company->id)
                ->where('is_default', true)
                ->update(['is_default' => false]);
        }

        $shift = Shift::create([
            'company_id' => $company->id,
            'name' => $validated['name'],
            'code' => $validated['code'] ?? null,
            'start_time' => $validated['start_time'],
            'end_time' => $validated['end_time'],
            'is_default' => $validated['is_default'] ?? false,
            'is_active' => $validated['is_active'] ?? true,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Shift berhasil dibuat',
            'data' => [
                'id' => $shift->id,
                'name' => $shift->name,
                'code' => $shift->code,
                'start_time' => $shift->start_time?->format('H:i'),
                'end_time' => $shift->end_time?->format('H:i'),
                'is_default' => $shift->is_default,
                'is_active' => $shift->is_active,
            ],
        ], 201);
    }

    /**
     * Update a shift (admin only)
     */
    public function update(Request $request, Shift $shift): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat mengubah shift',
            ], 403);
        }

        if ($shift->company_id !== $user->company_id && !$user->hasRole('super_admin')) {
            return response()->json([
                'success' => false,
                'message' => 'Shift tidak ditemukan',
            ], 404);
        }

        $validated = $request->validate([
            'name' => 'sometimes|string|max:255',
            'code' => 'nullable|string|max:50',
            'start_time' => 'sometimes|date_format:H:i',
            'end_time' => 'sometimes|date_format:H:i',
            'is_default' => 'sometimes|boolean',
            'is_active' => 'sometimes|boolean',
        ]);

        // If this shift is being set as default, unset others
        if (($validated['is_default'] ?? false) && !$shift->is_default) {
            Shift::where('company_id', $shift->company_id)
                ->where('id', '!=', $shift->id)
                ->where('is_default', true)
                ->update(['is_default' => false]);
        }

        $shift->update($validated);

        return response()->json([
            'success' => true,
            'message' => 'Shift berhasil diperbarui',
            'data' => [
                'id' => $shift->id,
                'name' => $shift->name,
                'code' => $shift->code,
                'start_time' => $shift->start_time?->format('H:i'),
                'end_time' => $shift->end_time?->format('H:i'),
                'is_default' => $shift->is_default,
                'is_active' => $shift->is_active,
            ],
        ]);
    }

    /**
     * Delete a shift (admin only)
     */
    public function destroy(Request $request, Shift $shift): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat menghapus shift',
            ], 403);
        }

        if ($shift->company_id !== $user->company_id && !$user->hasRole('super_admin')) {
            return response()->json([
                'success' => false,
                'message' => 'Shift tidak ditemukan',
            ], 404);
        }

        // Check if any users are assigned to this shift
        $activeAssignments = UserShift::where('shift_id', $shift->id)
            ->where(function ($q) {
                $q->whereNull('end_date')
                    ->orWhere('end_date', '>=', now()->toDateString());
            })
            ->count();

        if ($activeAssignments > 0) {
            return response()->json([
                'success' => false,
                'message' => "Tidak dapat menghapus shift. Masih ada {$activeAssignments} karyawan yang menggunakan shift ini.",
            ], 422);
        }

        $shift->delete();

        return response()->json([
            'success' => true,
            'message' => 'Shift berhasil dihapus',
        ]);
    }

    /**
     * Assign users to a shift (admin only)
     */
    public function assignUsers(Request $request, Shift $shift): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat mengatur shift karyawan',
            ], 403);
        }

        if ($shift->company_id !== $user->company_id && !$user->hasRole('super_admin')) {
            return response()->json([
                'success' => false,
                'message' => 'Shift tidak ditemukan',
            ], 404);
        }

        $validated = $request->validate([
            'user_ids' => 'required|array|min:1',
            'user_ids.*' => 'integer|exists:users,id',
            'effective_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:effective_date',
        ]);

        $assignedCount = 0;
        foreach ($validated['user_ids'] as $userId) {
            // Verify user belongs to same company
            $targetUser = User::find($userId);
            if (!$targetUser || ($targetUser->company_id !== $shift->company_id && !$user->hasRole('super_admin'))) {
                continue;
            }

            // End any existing active shift assignments for this user
            UserShift::where('user_id', $userId)
                ->where(function ($q) use ($validated) {
                    $q->whereNull('end_date')
                        ->orWhere('end_date', '>=', $validated['effective_date']);
                })
                ->update(['end_date' => \Carbon\Carbon::parse($validated['effective_date'])->subDay()->toDateString()]);

            // Create new assignment
            UserShift::create([
                'user_id' => $userId,
                'shift_id' => $shift->id,
                'effective_date' => $validated['effective_date'],
                'end_date' => $validated['end_date'] ?? null,
            ]);

            $assignedCount++;
        }

        return response()->json([
            'success' => true,
            'message' => "{$assignedCount} karyawan berhasil di-assign ke shift {$shift->name}",
            'assigned_count' => $assignedCount,
        ]);
    }

    /**
     * Remove a user from a shift (admin only)
     */
    public function removeUser(Request $request, Shift $shift, User $targetUser): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat mengatur shift karyawan',
            ], 403);
        }

        // Company ownership check
        if ($shift->company_id !== $user->company_id && !$user->hasRole('super_admin')) {
            return response()->json([
                'success' => false,
                'message' => 'Shift tidak ditemukan',
            ], 404);
        }

        // End active assignments
        UserShift::where('user_id', $targetUser->id)
            ->where('shift_id', $shift->id)
            ->where(function ($q) {
                $q->whereNull('end_date')
                    ->orWhere('end_date', '>=', now()->toDateString());
            })
            ->update(['end_date' => now()->toDateString()]);

        return response()->json([
            'success' => true,
            'message' => "Karyawan {$targetUser->name} berhasil dihapus dari shift {$shift->name}",
        ]);
    }

    /**
     * Get current shift for the authenticated user
     */
    public function myShift(Request $request): JsonResponse
    {
        $user = $request->user();
        $shift = $user->getCurrentShift();

        return response()->json([
            'success' => true,
            'data' => $shift ? [
                'id' => $shift->id,
                'name' => $shift->name,
                'code' => $shift->code,
                'start_time' => $shift->start_time?->format('H:i'),
                'end_time' => $shift->end_time?->format('H:i'),
                'is_default' => $shift->is_default,
            ] : null,
            'office_time_enabled' => $user->company?->office_time_enabled ?? false,
        ]);
    }

    /**
     * Get users with their shift assignments (admin only)
     */
    public function usersWithShifts(Request $request): JsonResponse
    {
        $user = $request->user();

        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat melihat data shift karyawan',
            ], 403);
        }

        $company = $user->company;
        $today = now()->toDateString();

        $users = User::where('company_id', $company->id)
            ->where('is_active', true)
            ->where('approval_status', 'approved')
            ->whereDoesntHave('roles', function ($q) {
                $q->where('name', 'super_admin');
            })
            ->with(['userShifts' => function ($q) use ($today) {
                $q->with('shift')
                  ->where('effective_date', '<=', $today)
                  ->where(function ($qq) use ($today) {
                      $qq->whereNull('end_date')
                          ->orWhere('end_date', '>=', $today);
                  })
                  ->orderBy('effective_date', 'desc');
            }])
            ->orderBy('name')
            ->get()
            ->map(function ($u) {
                $currentShift = $u->userShifts->first()?->shift;
                $assignment = $u->userShifts->first();

                return [
                    'id' => $u->id,
                    'name' => $u->name,
                    'employee_id' => $u->employee_id,
                    'nip' => $u->nip,
                    'department' => $u->department,
                    'position' => $u->position,
                    'current_shift' => $currentShift ? [
                        'id' => $currentShift->id,
                        'name' => $currentShift->name,
                        'code' => $currentShift->code,
                        'start_time' => $currentShift->start_time?->format('H:i'),
                        'end_time' => $currentShift->end_time?->format('H:i'),
                    ] : null,
                    'effective_date' => $assignment?->effective_date?->format('Y-m-d'),
                    'end_date' => $assignment?->end_date?->format('Y-m-d'),
                ];
            });

        return response()->json([
            'success' => true,
            'data' => $users,
        ]);
    }
}
