<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Overtime;
use App\Models\Holiday;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;

class OvertimeController extends Controller
{
    /**
     * Get list of overtimes for current user
     */
    public function index(Request $request): JsonResponse
    {
        $user = $request->user();

        $query = $user->overtimes()
            ->with(['attendance', 'approvedBy:id,name'])
            ->orderBy('date', 'desc');

        // Filter by status
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        // Filter by month/year
        if ($request->has('month') && $request->has('year')) {
            $query->whereMonth('date', $request->month)
                ->whereYear('date', $request->year);
        }

        $overtimes = $query->paginate($request->per_page ?? 15);

        return response()->json([
            'success' => true,
            'overtimes' => $overtimes->items(),
            'pagination' => [
                'current_page' => $overtimes->currentPage(),
                'last_page' => $overtimes->lastPage(),
                'per_page' => $overtimes->perPage(),
                'total' => $overtimes->total(),
            ],
        ]);
    }

    /**
     * Submit overtime claim
     */
    public function store(Request $request): JsonResponse
    {
        $user = $request->user();
        $company = $user->company;

        if (!$company->overtime_enabled) {
            return response()->json([
                'success' => false,
                'message' => 'Fitur lembur tidak aktif',
            ], 403);
        }

        $validated = $request->validate([
            'date' => 'required|date',
            'start_time' => 'required|date_format:H:i',
            'end_time' => 'required|date_format:H:i|after:start_time',
            'reason' => 'required|string|max:500',
            'notes' => 'nullable|string|max:1000',
            'attendance_id' => 'nullable|exists:attendances,id',
        ]);

        $date = Carbon::parse($validated['date']);

        // Determine overtime type
        $type = 'weekday';
        if ($company->isWeekend($date)) {
            $type = 'weekend';
        } elseif (Holiday::isHoliday($date, $company->id)) {
            $type = 'holiday';
        }

        // Calculate duration
        $startTime = Carbon::parse($validated['start_time']);
        $endTime = Carbon::parse($validated['end_time']);
        $durationMinutes = $endTime->diffInMinutes($startTime);

        // Check minimum overtime
        if ($durationMinutes < $company->minimum_overtime_minutes) {
            return response()->json([
                'success' => false,
                'message' => 'Durasi lembur minimal ' . $company->minimum_overtime_minutes . ' menit',
            ], 422);
        }

        // Check if already exists for this date
        $existingOvertime = Overtime::where('user_id', $user->id)
            ->where('date', $date->toDateString())
            ->whereNotIn('status', ['cancelled', 'rejected'])
            ->first();

        if ($existingOvertime) {
            return response()->json([
                'success' => false,
                'message' => 'Sudah ada pengajuan lembur untuk tanggal ini',
            ], 422);
        }

        $overtime = Overtime::create([
            'user_id' => $user->id,
            'company_id' => $company->id,
            'attendance_id' => $validated['attendance_id'] ?? null,
            'date' => $date->toDateString(),
            'start_time' => $validated['start_time'],
            'end_time' => $validated['end_time'],
            'duration_minutes' => $durationMinutes,
            'type' => $type,
            'reason' => $validated['reason'],
            'notes' => $validated['notes'] ?? null,
            'status' => $company->overtime_auto_approval ? 'approved' : 'pending',
            'approved_by' => $company->overtime_auto_approval ? $user->id : null,
            'approved_at' => $company->overtime_auto_approval ? now() : null,
        ]);

        return response()->json([
            'success' => true,
            'message' => $company->overtime_auto_approval
                ? 'Lembur berhasil diajukan dan otomatis disetujui'
                : 'Lembur berhasil diajukan, menunggu persetujuan',
            'overtime' => $overtime->load(['attendance', 'approvedBy:id,name']),
        ], 201);
    }

    /**
     * Get overtime details
     */
    public function show(Request $request, Overtime $overtime): JsonResponse
    {
        $user = $request->user();

        // Check access
        if ($overtime->user_id !== $user->id && !$user->hasRole(['super_admin', 'admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Tidak memiliki akses',
            ], 403);
        }

        return response()->json([
            'success' => true,
            'overtime' => $overtime->load(['user:id,name,employee_id', 'attendance', 'approvedBy:id,name']),
        ]);
    }

    /**
     * Cancel overtime (only if pending)
     */
    public function cancel(Request $request, Overtime $overtime): JsonResponse
    {
        $user = $request->user();

        if ($overtime->user_id !== $user->id) {
            return response()->json([
                'success' => false,
                'message' => 'Tidak memiliki akses',
            ], 403);
        }

        if (!$overtime->isPending()) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya lembur dengan status pending yang bisa dibatalkan',
            ], 422);
        }

        $overtime->update(['status' => 'cancelled']);

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

    /**
     * Get pending overtimes for approval (admin only)
     */
    public function pending(Request $request): JsonResponse
    {
        $user = $request->user();

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

        $overtimes = Overtime::where('company_id', $user->company_id)
            ->where('status', 'pending')
            ->with(['user:id,name,employee_id,department,position', 'attendance'])
            ->orderBy('date', 'desc')
            ->paginate($request->per_page ?? 15);

        return response()->json([
            'success' => true,
            'overtimes' => $overtimes->items(),
            'pagination' => [
                'current_page' => $overtimes->currentPage(),
                'last_page' => $overtimes->lastPage(),
                'per_page' => $overtimes->perPage(),
                'total' => $overtimes->total(),
            ],
        ]);
    }

    /**
     * Approve overtime (admin only)
     */
    public function approve(Request $request, Overtime $overtime): JsonResponse
    {
        $user = $request->user();

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

        if ($overtime->company_id !== $user->company_id) {
            return response()->json([
                'success' => false,
                'message' => 'Tidak memiliki akses',
            ], 403);
        }

        if (!$overtime->isPending()) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya lembur dengan status pending yang bisa disetujui',
            ], 422);
        }

        $overtime->update([
            'status' => 'approved',
            'approved_by' => $user->id,
            'approved_at' => now(),
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Lembur berhasil disetujui',
            'overtime' => $overtime->fresh()->load(['user:id,name', 'approvedBy:id,name']),
        ]);
    }

    /**
     * Reject overtime (admin only)
     */
    public function reject(Request $request, Overtime $overtime): JsonResponse
    {
        $user = $request->user();

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

        if ($overtime->company_id !== $user->company_id) {
            return response()->json([
                'success' => false,
                'message' => 'Tidak memiliki akses',
            ], 403);
        }

        if (!$overtime->isPending()) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya lembur dengan status pending yang bisa ditolak',
            ], 422);
        }

        $validated = $request->validate([
            'rejection_reason' => 'required|string|max:500',
        ]);

        $overtime->update([
            'status' => 'rejected',
            'rejection_reason' => $validated['rejection_reason'],
            'approved_by' => $user->id,
            'approved_at' => now(),
        ]);

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

    /**
     * Bulk approve overtimes (admin only)
     */
    public function bulkApprove(Request $request): JsonResponse
    {
        $user = $request->user();

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

        $validated = $request->validate([
            'overtime_ids' => 'required|array',
            'overtime_ids.*' => 'exists:overtimes,id',
        ]);

        $updated = Overtime::whereIn('id', $validated['overtime_ids'])
            ->where('company_id', $user->company_id)
            ->where('status', 'pending')
            ->update([
                'status' => 'approved',
                'approved_by' => $user->id,
                'approved_at' => now(),
            ]);

        return response()->json([
            'success' => true,
            'message' => "$updated lembur berhasil disetujui",
            'approved_count' => $updated,
        ]);
    }

    /**
     * Bulk reject/ignore overtimes (admin only)
     */
    public function bulkReject(Request $request): JsonResponse
    {
        $user = $request->user();

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

        $validated = $request->validate([
            'overtime_ids' => 'required|array',
            'overtime_ids.*' => 'exists:overtimes,id',
            'rejection_reason' => 'required|string|max:500',
        ]);

        $updated = Overtime::whereIn('id', $validated['overtime_ids'])
            ->where('company_id', $user->company_id)
            ->where('status', 'pending')
            ->update([
                'status' => 'rejected',
                'rejection_reason' => $validated['rejection_reason'],
                'approved_by' => $user->id,
                'approved_at' => now(),
            ]);

        return response()->json([
            'success' => true,
            'message' => "$updated lembur berhasil ditolak",
            'rejected_count' => $updated,
        ]);
    }

    /**
     * Get overtime summary for current user
     */
    public function summary(Request $request): JsonResponse
    {
        $user = $request->user();
        $month = $request->month ?? now()->month;
        $year = $request->year ?? now()->year;

        $overtimes = Overtime::where('user_id', $user->id)
            ->whereMonth('date', $month)
            ->whereYear('date', $year)
            ->get();

        $summary = [
            'total_submitted' => $overtimes->count(),
            'pending' => $overtimes->where('status', 'pending')->count(),
            'approved' => $overtimes->where('status', 'approved')->count(),
            'rejected' => $overtimes->where('status', 'rejected')->count(),
            'total_approved_minutes' => $overtimes->where('status', 'approved')->sum('duration_minutes'),
            'total_approved_hours' => round($overtimes->where('status', 'approved')->sum('duration_minutes') / 60, 1),
            'by_type' => [
                'weekday' => $overtimes->where('status', 'approved')->where('type', 'weekday')->sum('duration_minutes'),
                'weekend' => $overtimes->where('status', 'approved')->where('type', 'weekend')->sum('duration_minutes'),
                'holiday' => $overtimes->where('status', 'approved')->where('type', 'holiday')->sum('duration_minutes'),
            ],
        ];

        return response()->json([
            'success' => true,
            'month' => $month,
            'year' => $year,
            'summary' => $summary,
        ]);
    }
}
