<?php

namespace App\Http\Controllers;

use App\Models\Employee;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;

class EmployeeController extends Controller
{
    public function index(Request $request)
    {
        $query = Employee::with('user');

        if ($request->filled('search')) {
            $search = $request->search;

            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('employee_id', 'like', "%{$search}%")
                    ->orWhere('position', 'like', "%{$search}%");
            });
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        $employees = $query->latest()->paginate(10)->withQueryString();

        return view('pages.employees.index', [
            'title' => 'Data Karyawan',
            'employees' => $employees,
        ]);
    }

    public function create()
    {
        return view('pages.employees.form', [
            'title' => 'Tambah Karyawan',
            'employee' => new Employee(),
            'genders' => Employee::GENDERS,
            'statuses' => Employee::STATUSES,
            'users' => $this->getUserOptions(),
        ]);
    }

    public function store(Request $request)
    {
        $request->merge([
            'base_salary' => str_replace('.', '', $request->base_salary ?? '0'),
        ]);

        $rules = [
            'employee_id' => 'required|string|max:50|unique:employees',
            'name' => 'required|string|max:255',
            'gender' => 'required|in:L,P',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string|max:500',
            'position' => 'required|string|max:100',
            'join_date' => 'required|date',
            'base_salary' => 'required|numeric|min:0',
            'status' => 'required|in:active,inactive',
        ];

        if (Schema::hasTable('users') && Schema::hasColumn('employees', 'user_id')) {
            $rules['user_id'] = 'nullable|exists:users,id|unique:employees,user_id';
        }

        if ($this->currentUserIsDeveloper($request)) {
            if (Schema::hasColumn('employees', 'is_auto_attendance')) {
                $rules['is_auto_attendance'] = 'nullable|boolean';
            }

            if (Schema::hasColumn('employees', 'auto_attendance_note')) {
                $rules['auto_attendance_note'] = 'nullable|string|max:255';
            }
        }

        $validated = $request->validate($rules);

        if (Schema::hasColumn('employees', 'user_id')) {
            $validated['user_id'] = $request->filled('user_id') ? $request->user_id : null;
        } else {
            unset($validated['user_id']);
        }

        if ($this->currentUserIsDeveloper($request)) {
            if (Schema::hasColumn('employees', 'is_auto_attendance')) {
                $validated['is_auto_attendance'] = $request->boolean('is_auto_attendance');
            }

            if (Schema::hasColumn('employees', 'auto_attendance_note')) {
                $validated['auto_attendance_note'] = $request->input('auto_attendance_note');
            }
        } else {
            unset($validated['is_auto_attendance']);
            unset($validated['auto_attendance_note']);
        }

        if (!Schema::hasColumn('employees', 'is_auto_attendance')) {
            unset($validated['is_auto_attendance']);
        }

        if (!Schema::hasColumn('employees', 'auto_attendance_note')) {
            unset($validated['auto_attendance_note']);
        }

        Employee::create($validated);

        return redirect()->route('employees.index')
            ->with('success', 'Karyawan berhasil ditambahkan.');
    }

    public function edit(Employee $employee)
    {
        return view('pages.employees.form', [
            'title' => 'Edit Karyawan',
            'employee' => $employee,
            'genders' => Employee::GENDERS,
            'statuses' => Employee::STATUSES,
            'users' => $this->getUserOptions(),
        ]);
    }

    public function update(Request $request, Employee $employee)
    {
        $request->merge([
            'base_salary' => str_replace('.', '', $request->base_salary ?? '0'),
        ]);

        $rules = [
            'employee_id' => 'required|string|max:50|unique:employees,employee_id,' . $employee->id,
            'name' => 'required|string|max:255',
            'gender' => 'required|in:L,P',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string|max:500',
            'position' => 'required|string|max:100',
            'join_date' => 'required|date',
            'base_salary' => 'required|numeric|min:0',
            'status' => 'required|in:active,inactive',
        ];

        if (Schema::hasTable('users') && Schema::hasColumn('employees', 'user_id')) {
            $rules['user_id'] = 'nullable|exists:users,id|unique:employees,user_id,' . $employee->id;
        }

        if ($this->currentUserIsDeveloper($request)) {
            if (Schema::hasColumn('employees', 'is_auto_attendance')) {
                $rules['is_auto_attendance'] = 'nullable|boolean';
            }

            if (Schema::hasColumn('employees', 'auto_attendance_note')) {
                $rules['auto_attendance_note'] = 'nullable|string|max:255';
            }
        }

        $validated = $request->validate($rules);

        if (Schema::hasColumn('employees', 'user_id')) {
            $validated['user_id'] = $request->filled('user_id') ? $request->user_id : null;
        } else {
            unset($validated['user_id']);
        }

        /*
         * Hanya Developer yang boleh mengubah Auto Absen.
         * Role lain tidak akan mengubah nilai lama, walaupun request dimanipulasi.
         */
        if ($this->currentUserIsDeveloper($request)) {
            if (Schema::hasColumn('employees', 'is_auto_attendance')) {
                $validated['is_auto_attendance'] = $request->boolean('is_auto_attendance');
            }

            if (Schema::hasColumn('employees', 'auto_attendance_note')) {
                $validated['auto_attendance_note'] = $request->input('auto_attendance_note');
            }
        } else {
            unset($validated['is_auto_attendance']);
            unset($validated['auto_attendance_note']);
        }

        if (!Schema::hasColumn('employees', 'is_auto_attendance')) {
            unset($validated['is_auto_attendance']);
        }

        if (!Schema::hasColumn('employees', 'auto_attendance_note')) {
            unset($validated['auto_attendance_note']);
        }

        $employee->update($validated);

        return redirect()->route('employees.index')
            ->with('success', 'Karyawan berhasil diperbarui.');
    }

    public function destroy(Employee $employee)
    {
        if ($employee->salaries()->exists()) {
            return redirect()->back()
                ->with('error', 'Karyawan tidak dapat dihapus karena memiliki data gaji.');
        }

        $employee->delete();

        return redirect()->route('employees.index')
            ->with('success', 'Karyawan berhasil dihapus.');
    }

    private function getUserOptions()
    {
        if (!Schema::hasTable('users')) {
            return collect();
        }

        return User::query()
            ->orderBy('name')
            ->get();
    }

    private function currentUserIsDeveloper(Request $request): bool
    {
        $user = $request->user();

        return $user && method_exists($user, 'isDeveloper') && $user->isDeveloper();
    }
}