<?php

namespace App\Services;

use App\Models\Activity;
use App\Models\Attendance;
use App\Models\User;
use Carbon\Carbon;

class ActivityService
{
    /**
     * Membuat aktivitas baru
     */
    public function create(
        User $user,
        string $date,
        string $startTime,
        string $endTime,
        string $activity,
        ?string $output = null,
        ?string $notes = null
    ): array {
        // Validasi backdate_enabled
        $company = $user->company;
        $activityDate = Carbon::parse($date);
        
        if (!$company->backdate_enabled && $activityDate->isPast() && !$activityDate->isToday()) {
            return [
                'success' => false,
                'message' => 'Tidak dapat membuat aktivitas untuk tanggal sebelumnya. Fitur backdate dinonaktifkan.',
            ];
        }

        // Validasi waktu
        $start = Carbon::parse("{$date} {$startTime}");
        $end = Carbon::parse("{$date} {$endTime}");

        if ($end->lessThanOrEqualTo($start)) {
            return [
                'success' => false,
                'message' => 'Waktu selesai harus setelah waktu mulai',
            ];
        }

        // Cek apakah ada attendance untuk tanggal tersebut (REQUIRED)
        $attendance = Attendance::where('user_id', $user->id)
            ->whereDate('date', $date)
            ->first();

        if (!$attendance) {
            return [
                'success' => false,
                'message' => 'Tidak dapat membuat aktivitas tanpa kehadiran. Silakan check-in terlebih dahulu.',
            ];
        }

        // Validasi waktu aktivitas harus dalam range check-in/check-out
        if ($attendance->check_in_time) {
            $checkInTime = Carbon::parse($attendance->check_in_time);
            if ($start->lessThan($checkInTime)) {
                return [
                    'success' => false,
                    'message' => 'Waktu mulai aktivitas tidak boleh sebelum waktu check-in',
                ];
            }
        }

        if ($attendance->check_out_time) {
            $checkOutTime = Carbon::parse($attendance->check_out_time);
            if ($end->greaterThan($checkOutTime)) {
                return [
                    'success' => false,
                    'message' => 'Waktu selesai aktivitas tidak boleh setelah waktu check-out',
                ];
            }
        }

        // Cek apakah sudah ada aktivitas dengan waktu yang overlap
        $overlapping = Activity::where('user_id', $user->id)
            ->whereDate('date', $date)
            ->where(function ($query) use ($start, $end) {
                $query->where(function ($q) use ($start, $end) {
                    // Start time dalam range
                    $q->where('start_time', '<=', $start->format('H:i:s'))
                        ->where('end_time', '>', $start->format('H:i:s'));
                })->orWhere(function ($q) use ($start, $end) {
                    // End time dalam range
                    $q->where('start_time', '<', $end->format('H:i:s'))
                        ->where('end_time', '>=', $end->format('H:i:s'));
                })->orWhere(function ($q) use ($start, $end) {
                    // Aktivitas baru mencakup aktivitas yang sudah ada
                    $q->where('start_time', '>=', $start->format('H:i:s'))
                        ->where('end_time', '<=', $end->format('H:i:s'));
                });
            })
            ->exists();

        if ($overlapping) {
            return [
                'success' => false,
                'message' => 'Waktu aktivitas bertabrakan dengan aktivitas yang sudah ada',
            ];
        }

        try {
            $activity = Activity::create([
                'user_id' => $user->id,
                'attendance_id' => $attendance->id, // Required now
                'date' => $date,
                'start_time' => $startTime,
                'end_time' => $endTime,
                'activity' => $activity,
                'output' => $output,
                'notes' => $notes,
            ]);

            return [
                'success' => true,
                'message' => 'Aktivitas berhasil dibuat',
                'activity' => $activity->load('attendance'),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Gagal membuat aktivitas: ' . $e->getMessage(),
            ];
        }
    }

    /**
     * Update aktivitas
     */
    public function update(
        Activity $activity,
        string $startTime,
        string $endTime,
        string $activityText,
        ?string $output = null,
        ?string $notes = null
    ): array {
        // Validasi waktu - pastikan date dalam format Y-m-d
        $dateStr = $activity->date instanceof Carbon ? $activity->date->format('Y-m-d') : $activity->date;
        $start = Carbon::parse("{$dateStr} {$startTime}");
        $end = Carbon::parse("{$dateStr} {$endTime}");

        if ($end->lessThanOrEqualTo($start)) {
            return [
                'success' => false,
                'message' => 'Waktu selesai harus setelah waktu mulai',
            ];
        }

        // Cek apakah ada aktivitas lain dengan waktu yang overlap (kecuali aktivitas ini)
        $overlapping = Activity::where('user_id', $activity->user_id)
            ->whereDate('date', $activity->date)
            ->where('id', '!=', $activity->id)
            ->where(function ($query) use ($start, $end) {
                $query->where(function ($q) use ($start, $end) {
                    $q->where('start_time', '<=', $start->format('H:i:s'))
                        ->where('end_time', '>', $start->format('H:i:s'));
                })->orWhere(function ($q) use ($start, $end) {
                    $q->where('start_time', '<', $end->format('H:i:s'))
                        ->where('end_time', '>=', $end->format('H:i:s'));
                })->orWhere(function ($q) use ($start, $end) {
                    $q->where('start_time', '>=', $start->format('H:i:s'))
                        ->where('end_time', '<=', $end->format('H:i:s'));
                });
            })
            ->exists();

        if ($overlapping) {
            return [
                'success' => false,
                'message' => 'Waktu aktivitas bertabrakan dengan aktivitas yang sudah ada',
            ];
        }

        try {
            $activity->update([
                'start_time' => $startTime,
                'end_time' => $endTime,
                'activity' => $activityText,
                'output' => $output,
                'notes' => $notes,
            ]);

            return [
                'success' => true,
                'message' => 'Aktivitas berhasil diupdate',
                'activity' => $activity->fresh()->load('attendance'),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Gagal mengupdate aktivitas: ' . $e->getMessage(),
            ];
        }
    }

    /**
     * Mendapatkan aktivitas berdasarkan tanggal
     */
    public function getByDate(User $user, string $date): array
    {
        $activities = Activity::where('user_id', $user->id)
            ->whereDate('date', $date)
            ->orderBy('start_time')
            ->get();

        return [
            'success' => true,
            'activities' => $activities,
        ];
    }

    /**
     * Mendapatkan aktivitas berdasarkan attendance
     */
    public function getByAttendance(Attendance $attendance): array
    {
        $activities = Activity::where('attendance_id', $attendance->id)
            ->orderBy('start_time')
            ->get();

        return [
            'success' => true,
            'activities' => $activities,
        ];
    }
}

