<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AttendanceCorrection;
use App\Models\BusinessTrip;
use App\Models\Company;
use App\Models\EarlyLeaveRequest;
use App\Models\LateArrivalRequest;
use App\Models\Location;
use App\Services\ActivityAssignmentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class SettingsController extends Controller
{
    /**
     * Mendapatkan semua pengaturan
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $user = $request->user();
            $company = $user->company;

            // Cek apakah user adalah super admin (hanya super_admin yang bisa edit settings)
            $isSuperAdmin = $user->hasRole('super_admin');

            // Get user's current shift (wrapped for safety)
            $currentShift = null;
            try {
                $currentShift = $user->getCurrentShift();
            } catch (\Exception $e) {
                \Log::warning('getCurrentShift error: ' . $e->getMessage());
            }

            // Check if today is a holiday (wrapped for safety)
            $isHoliday = false;
            try {
                $isHoliday = $company->isHoliday(now());
            } catch (\Exception $e) {
                \Log::warning('isHoliday error: ' . $e->getMessage());
            }

            return response()->json([
            'success' => true,
            'settings' => [
                'location_editable' => $company->allow_editable_location ?? true,
                'device_validation_enabled' => $company->device_validation_enabled ?? false,
                'max_devices_per_user' => $company->max_devices_per_user ?? 3,
                'backdate_enabled' => $company->backdate_enabled ?? true,
                'allow_business_trip' => $company->allow_business_trip ?? true,
                'attendance_auto_enabled' => $company->attendance_auto_enabled ?? true,
                'allow_document_upload' => $company->allow_document_upload ?? true,
                'bypass_claim_approval' => $company->bypass_claim_approval ?? false,
                'office_time_enabled' => $company->office_time_enabled ?? false,
                'late_tolerance_minutes' => $company->late_tolerance_minutes ?? 15,
                'check_in_reminder' => $company->alarm_enabled ?? true,
                'check_out_reminder' => $company->alarm_enabled ?? true,
                'check_in_time' => $company->work_start_time?->format('H:i') ?? '08:00',
                'check_out_time' => $company->work_end_time?->format('H:i') ?? '17:00',
                'checkin_reminder_time' => $company->checkin_reminder_time?->format('H:i'),
                'checkout_reminder_after_hours' => $company->checkout_reminder_after_hours ?? 9,
                'allow_employee_edit_home_location' => $company->allow_employee_edit_home_location ?? false,
                'show_recap_for_admin' => $company->show_recap_for_admin ?? true,
                'show_recap_for_employee' => $company->show_recap_for_employee ?? true,
            ],
            'holiday_settings' => [
                'weekend_days' => $company->weekend_days ?? [0, 6],
                'is_today_holiday' => $isHoliday,
                'overtime_enabled' => $company->overtime_enabled ?? true,
                'overtime_auto_approval' => $company->overtime_auto_approval ?? false,
                'minimum_overtime_minutes' => $company->minimum_overtime_minutes ?? 30,
            ],
            // checkout_after_hours: bila pakai shift, isi durasi shift (jam) agar mobile (check_in + hours) ≈ jam pulang shift
            'alarm_settings' => [
                'enabled' => $company->alarm_enabled ?? true,
                'checkin_time' => $company->checkin_reminder_time?->format('H:i') ?? $company->work_start_time?->format('H:i') ?? '08:00',
                'checkout_after_hours' => $this->getCheckoutAfterHoursForUser($company, $currentShift),
                'weekend_days' => $company->weekend_days ?? [0, 6],
                'is_today_working_day' => !$isHoliday,
            ],
            'shift' => $currentShift ? [
                'id' => $currentShift->id,
                'name' => $currentShift->name,
                'start_time' => $currentShift->start_time?->format('H:i'),
                'end_time' => $currentShift->end_time?->format('H:i'),
            ] : null,
            'support' => [
                'phone' => $company->support_phone,
                'email' => $company->support_email ?? $company->email,
                'company_name' => $company->name,
            ],
            'company_location' => $this->getCompanyLocationData($company),
            'is_admin' => $user->hasRole(['admin', 'super_admin']),
            'is_super_admin' => $isSuperAdmin,
            'can_edit_settings' => $isSuperAdmin,
            'can_edit_recap_settings' => $user->hasRole(['admin', 'super_admin']), // Admin & Super Admin can edit recap settings
            'navigation' => $this->getNavigationConfig($user, $company),
        ]);
        } catch (\Exception $e) {
            \Log::error('Settings index error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal memuat pengaturan: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Mendapatkan pengaturan aktivitas
     */
    public function activity(Request $request): JsonResponse
    {
        $user = $request->user();
        $company = $user->company;

        return response()->json([
            'success' => true,
            'activity_settings' => [
                'backdate_enabled' => $company->backdate_enabled ?? true,
            ],
        ]);
    }

    /**
     * Update pengaturan company
     * - Super Admin: can edit all settings
     * - Admin: can only edit recap settings (show_recap_for_admin, show_recap_for_employee)
     */
    public function update(Request $request): JsonResponse
    {
        $user = $request->user();

        // Check if user is admin or super admin - same as updateCompanyLocation
        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat mengubah pengaturan',
            ], 403);
        }

        $isSuperAdmin = $user->hasRole('super_admin');

        // Admin biasa hanya boleh update recap settings
        $recapOnlyFields = ['show_recap_for_admin', 'show_recap_for_employee'];
        if (!$isSuperAdmin) {
            // Check if admin is trying to update non-recap settings
            $requestedFields = array_keys($request->only([
                'location_editable', 'device_validation_enabled', 'max_devices_per_user',
                'backdate_enabled', 'allow_business_trip', 'attendance_auto_enabled',
                'allow_document_upload', 'bypass_claim_approval', 'office_time_enabled',
                'late_tolerance_minutes', 'weekend_days', 'alarm_enabled',
                'checkin_reminder_time', 'checkout_reminder_after_hours',
                'overtime_enabled', 'overtime_auto_approval', 'minimum_overtime_minutes',
            ]));

            if (!empty($requestedFields)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Admin hanya dapat mengubah pengaturan menu Rekap. Pengaturan lain hanya bisa diubah oleh Super Admin.',
                ], 403);
            }
        }

        $validated = $request->validate([
            'location_editable' => 'sometimes|boolean',
            'device_validation_enabled' => 'sometimes|boolean',
            'max_devices_per_user' => 'sometimes|integer|min:1|max:10',
            'backdate_enabled' => 'sometimes|boolean',
            'allow_business_trip' => 'sometimes|boolean',
            'attendance_auto_enabled' => 'sometimes|boolean',
            'allow_document_upload' => 'sometimes|boolean',
            'bypass_claim_approval' => 'sometimes|boolean',
            'office_time_enabled' => 'sometimes|boolean',
            'late_tolerance_minutes' => 'sometimes|integer|min:0|max:60',
            'weekend_days' => 'sometimes|array',
            'weekend_days.*' => 'integer|between:0,6',
            'alarm_enabled' => 'sometimes|boolean',
            'checkin_reminder_time' => 'sometimes|nullable|date_format:H:i',
            'checkout_reminder_after_hours' => 'sometimes|integer|min:1|max:24',
            'overtime_enabled' => 'sometimes|boolean',
            'overtime_auto_approval' => 'sometimes|boolean',
            'minimum_overtime_minutes' => 'sometimes|integer|min:15|max:480',
            'show_recap_for_admin' => 'sometimes|boolean',
            'show_recap_for_employee' => 'sometimes|boolean',
        ]);

        $company = $user->company;

        // Map field names dari API ke database
        $fieldMapping = [
            'location_editable' => 'allow_editable_location',
            'device_validation_enabled' => 'device_validation_enabled',
            'max_devices_per_user' => 'max_devices_per_user',
            'backdate_enabled' => 'backdate_enabled',
            'allow_business_trip' => 'allow_business_trip',
            'attendance_auto_enabled' => 'attendance_auto_enabled',
            'allow_document_upload' => 'allow_document_upload',
            'bypass_claim_approval' => 'bypass_claim_approval',
            'office_time_enabled' => 'office_time_enabled',
            'late_tolerance_minutes' => 'late_tolerance_minutes',
            'weekend_days' => 'weekend_days',
            'alarm_enabled' => 'alarm_enabled',
            'checkin_reminder_time' => 'checkin_reminder_time',
            'checkout_reminder_after_hours' => 'checkout_reminder_after_hours',
            'overtime_enabled' => 'overtime_enabled',
            'overtime_auto_approval' => 'overtime_auto_approval',
            'minimum_overtime_minutes' => 'minimum_overtime_minutes',
            'show_recap_for_admin' => 'show_recap_for_admin',
            'show_recap_for_employee' => 'show_recap_for_employee',
        ];

        $updateData = [];
        foreach ($validated as $key => $value) {
            if (isset($fieldMapping[$key])) {
                $updateData[$fieldMapping[$key]] = $value;
            }
        }

        if (!empty($updateData)) {
            $company->update($updateData);
        }

        return response()->json([
            'success' => true,
            'message' => 'Pengaturan berhasil diperbarui',
            'settings' => [
                'location_editable' => $company->allow_editable_location ?? true,
                'device_validation_enabled' => $company->device_validation_enabled ?? false,
                'max_devices_per_user' => $company->max_devices_per_user ?? 3,
                'backdate_enabled' => $company->backdate_enabled ?? true,
                'allow_business_trip' => $company->allow_business_trip ?? true,
                'attendance_auto_enabled' => $company->attendance_auto_enabled ?? true,
                'allow_document_upload' => $company->allow_document_upload ?? true,
                'bypass_claim_approval' => $company->bypass_claim_approval ?? false,
                'office_time_enabled' => $company->office_time_enabled ?? false,
                'late_tolerance_minutes' => $company->late_tolerance_minutes ?? 15,
            ],
            'holiday_settings' => [
                'weekend_days' => $company->weekend_days ?? [0, 6],
                'overtime_enabled' => $company->overtime_enabled ?? true,
                'overtime_auto_approval' => $company->overtime_auto_approval ?? false,
                'minimum_overtime_minutes' => $company->minimum_overtime_minutes ?? 30,
            ],
            'alarm_settings' => [
                'enabled' => $company->alarm_enabled ?? true,
                'checkin_time' => $company->checkin_reminder_time?->format('H:i'),
                'checkout_after_hours' => $company->checkout_reminder_after_hours ?? 9,
                'weekend_days' => $company->weekend_days ?? [0, 6],
                'is_today_working_day' => !$company->isHoliday(now()),
            ],
        ]);
    }

    /**
     * Nilai checkout_after_hours untuk response: bila pakai shift, pakai durasi shift (jam) agar
     * mobile (check_in + hours) mendekati jam pulang shift. Response sama, compatible dengan mobile.
     */
    protected function getCheckoutAfterHoursForUser($company, $currentShift): int
    {
        if ($company->office_time_enabled && $currentShift && $currentShift->start_time && $currentShift->end_time) {
            $start = \Carbon\Carbon::parse($currentShift->start_time);
            $end = \Carbon\Carbon::parse($currentShift->end_time);
            $hours = (int) round($start->diffInMinutes($end) / 60);
            return max(1, $hours);
        }
        return (int) ($company->checkout_reminder_after_hours ?? 9);
    }

    /**
     * Get company location data (check both company and locations table)
     */
    protected function getCompanyLocationData($company): array
    {
        // First, check if company has location set directly
        if ($company->latitude && $company->longitude) {
            return [
                'latitude' => (float) $company->latitude,
                'longitude' => (float) $company->longitude,
                'radius' => $company->radius ?? 100,
                'address' => $company->address,
                'has_location' => true,
                'source' => 'company',
            ];
        }

        // Fallback: check locations table for primary HQ
        $primaryLocation = Location::where('company_id', $company->id)
            ->where('is_primary', true)
            ->where('is_active', true)
            ->first();

        if ($primaryLocation) {
            return [
                'latitude' => (float) $primaryLocation->latitude,
                'longitude' => (float) $primaryLocation->longitude,
                'radius' => $primaryLocation->radius ?? 100,
                'address' => $primaryLocation->address,
                'has_location' => true,
                'source' => 'location',
                'location_id' => $primaryLocation->id,
                'location_name' => $primaryLocation->name,
            ];
        }

        // No location found
        return [
            'latitude' => null,
            'longitude' => null,
            'radius' => $company->radius ?? 100,
            'address' => $company->address,
            'has_location' => false,
            'source' => null,
        ];
    }

    /**
     * Get company location
     */
    public function getCompanyLocation(Request $request): JsonResponse
    {
        $user = $request->user();
        $company = $user->company;

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

    /**
     * Get navigation configuration for mobile app.
     */
    protected function getNavigationConfig($user, $company): array
    {
        // Wrap in try-catch in case ActivityAssignmentRule table doesn't exist yet
        $isActivityMandatory = false;
        try {
            $activityAssignmentService = app(ActivityAssignmentService::class);
            $isActivityMandatory = $activityAssignmentService->isActivityMandatoryForUser($user);
        } catch (\Exception $e) {
            // Table might not exist yet, silently fail
            \Log::warning('ActivityAssignmentService error: ' . $e->getMessage());
        }
        $isAdmin = $user->hasRole(['admin', 'super_admin']);

        // Get pending counts for admin (wrapped in try-catch for safety)
        $pendingCounts = null;
        if ($isAdmin) {
            try {
                $pendingCounts = [
                    'corrections' => AttendanceCorrection::where('company_id', $company->id)
                        ->where('status', 'pending')->count(),
                    'early_leave' => EarlyLeaveRequest::where('company_id', $company->id)
                        ->where('status', 'pending')->count(),
                    'late_arrival' => LateArrivalRequest::where('company_id', $company->id)
                        ->where('status', 'pending')->count(),
                    'business_trips' => BusinessTrip::where('company_id', $company->id)
                        ->where('status', 'pending')->count(),
                ];
            } catch (\Exception $e) {
                // Tables might not exist yet
                \Log::warning('Pending counts error: ' . $e->getMessage());
                $pendingCounts = ['corrections' => 0, 'early_leave' => 0, 'late_arrival' => 0, 'business_trips' => 0];
            }
        }

        return [
            'activity_mandatory' => $isActivityMandatory,
            'show_activity_tab' => $isActivityMandatory,
            'show_approval_tab' => $isAdmin && !$isActivityMandatory,
            'show_pengajuan_tab' => !$isAdmin && !$isActivityMandatory,
            'show_recap_for_admin' => $company->show_recap_for_admin ?? true,
            'show_recap_for_employee' => $company->show_recap_for_employee ?? true,
            'qr_card_enabled' => $company->qr_card_enabled ?? false,
            'qr_scanner_enabled' => $company->qr_scanner_enabled ?? false,
            'can_scan_qr' => $isAdmin && ($company->qr_scanner_enabled ?? false),
            'pending_counts' => $pendingCounts,
            'total_pending' => $pendingCounts ? array_sum($pendingCounts) : 0,
        ];
    }

    /**
     * Update company location (admin/super admin only)
     */
    public function updateCompanyLocation(Request $request): JsonResponse
    {
        $user = $request->user();

        // Check if user is admin or super admin
        if (!$user->hasRole(['admin', 'super_admin'])) {
            return response()->json([
                'success' => false,
                'message' => 'Hanya admin yang dapat mengubah lokasi perusahaan',
            ], 403);
        }

        $validated = $request->validate([
            'latitude' => 'required|numeric|between:-90,90',
            'longitude' => 'required|numeric|between:-180,180',
            'address' => 'nullable|string|max:500',
        ]);

        $company = $user->company;

        // 1. Update company table (backward compatibility)
        $company->update([
            'latitude' => $validated['latitude'],
            'longitude' => $validated['longitude'],
            'address' => $validated['address'] ?? $company->address,
        ]);

        // 2. Sync to locations table (create/update primary HQ location)
        $primaryLocation = Location::updateOrCreate(
            [
                'company_id' => $company->id,
                'is_primary' => true,
            ],
            [
                'name' => $company->name . ' - Kantor Pusat',
                'code' => 'HQ-' . $company->code,
                'address' => $validated['address'] ?? $company->address,
                'latitude' => $validated['latitude'],
                'longitude' => $validated['longitude'],
                'radius' => $company->radius ?? 100,
                'category' => 'internal',
                'type' => 'headquarters',
                'allow_daily_checkin' => true,
                'allow_business_trip' => false,
                'is_active' => true,
            ]
        );

        return response()->json([
            'success' => true,
            'message' => 'Lokasi perusahaan berhasil diperbarui',
            'data' => [
                'id' => $company->id,
                'name' => $company->name,
                'latitude' => $company->latitude,
                'longitude' => $company->longitude,
                'address' => $company->address,
                'radius' => $company->radius,
                'location_id' => $primaryLocation->id,
            ],
        ]);
    }
}
