<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\Announcement;
use App\Models\AttendanceRecord;
use App\Models\HrTicket;
use App\Models\LeaveRequest;
use App\Models\LeaveType;
use App\Models\Payroll;
use App\Models\Training;
use App\Models\TrainingEnrollment;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class PortalController extends Controller
{
    public function dashboard()
    {
        $user = auth()->user();

        return view('user.dashboard', [
            'user' => $user->load(['department', 'designation']),
            'todayAttendance' => AttendanceRecord::where('user_id', $user->id)->whereDate('work_date', today())->first(),
            'pendingLeaves' => LeaveRequest::where('user_id', $user->id)->where('status', 'pending')->count(),
            'latestPayroll' => Payroll::where('user_id', $user->id)->latest('pay_period_end')->first(),
            'openTickets' => HrTicket::where('user_id', $user->id)->whereIn('status', ['open', 'in_progress'])->count(),
            'announcements' => Announcement::where('status', 'published')->whereIn('audience', ['all', 'users'])->latest('published_at')->limit(5)->get(),
        ]);
    }

    public function profile()
    {
        return view('user.profile', ['user' => auth()->user()->load(['department', 'designation'])]);
    }

    public function updateProfile(Request $request)
    {
        $user = auth()->user();
        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'phone' => ['nullable', 'string', 'max:50'],
            'gender' => ['nullable', 'string', 'max:30'],
            'date_of_birth' => ['nullable', 'date'],
            'address' => ['nullable', 'string', 'max:255'],
            'emergency_contact' => ['nullable', 'string', 'max:255'],
            'bank_name' => ['nullable', 'string', 'max:255'],
            'bank_account' => ['nullable', 'string', 'max:100'],
            'password' => ['nullable', 'confirmed', 'min:8'],
        ]);
        if (! filled($data['password'] ?? null)) {
            unset($data['password']);
        }
        $user->update($data);

        return back()->with('success', 'Profile updated successfully.');
    }

    public function attendance()
    {
        return view('user.attendance', [
            'todayAttendance' => AttendanceRecord::where('user_id', auth()->id())->whereDate('work_date', today())->first(),
            'records' => AttendanceRecord::where('user_id', auth()->id())->latest('work_date')->paginate(20),
        ]);
    }

    public function clockIn()
    {
        AttendanceRecord::firstOrCreate(
            ['user_id' => auth()->id(), 'work_date' => today()->toDateString()],
            ['clock_in_at' => now(), 'status' => 'present']
        );

        return back()->with('success', 'Clock-in recorded.');
    }

    public function clockOut()
    {
        $record = AttendanceRecord::where('user_id', auth()->id())->whereDate('work_date', today())->first();
        if (! $record) {
            return back()->with('error', 'You must clock in before clocking out.');
        }
        $record->update(['clock_out_at' => now()]);

        return back()->with('success', 'Clock-out recorded.');
    }

    public function leaves()
    {
        return view('user.leaves', [
            'leaveTypes' => LeaveType::where('status', 'active')->orderBy('name')->get(),
            'leaves' => LeaveRequest::with('leaveType')->where('user_id', auth()->id())->latest()->paginate(20),
        ]);
    }

    public function storeLeave(Request $request)
    {
        $data = $request->validate([
            'leave_type_id' => ['required', 'exists:leave_types,id'],
            'start_date' => ['required', 'date'],
            'end_date' => ['required', 'date', 'after_or_equal:start_date'],
            'reason' => ['nullable', 'string'],
            'document' => ['nullable', 'file', 'max:5120'],
        ]);

        $data['user_id'] = auth()->id();
        $data['total_days'] = Carbon::parse($data['start_date'])->diffInDays(Carbon::parse($data['end_date'])) + 1;
        $data['status'] = 'pending';
        if ($request->hasFile('document')) {
            $data['document_path'] = $request->file('document')->store('leave-documents', 'public');
        }
        unset($data['document']);
        LeaveRequest::create($data);

        return back()->with('success', 'Leave request submitted.');
    }

    public function payslips()
    {
        return view('user.payslips', [
            'payrolls' => Payroll::where('user_id', auth()->id())->latest('pay_period_end')->paginate(20),
        ]);
    }

    public function documents()
    {
        return view('user.documents', [
            'documents' => auth()->user()->documents()->latest()->paginate(20),
        ]);
    }

    public function announcements()
    {
        return view('user.announcements', [
            'announcements' => Announcement::where('status', 'published')->whereIn('audience', ['all', 'users'])->latest('published_at')->paginate(20),
        ]);
    }

    public function performance()
    {
        return view('user.performance', [
            'reviews' => auth()->user()->performanceReviews()->latest()->paginate(20),
        ]);
    }

    public function trainings()
    {
        return view('user.trainings', [
            'trainings' => Training::where('status', 'active')->latest()->paginate(20),
            'enrolledIds' => auth()->user()->trainings()->pluck('trainings.id')->toArray(),
        ]);
    }

    public function enrollTraining(Training $training)
    {
        TrainingEnrollment::firstOrCreate([
            'training_id' => $training->id,
            'user_id' => auth()->id(),
        ], ['status' => 'registered']);

        return back()->with('success', 'Training registration completed.');
    }

    public function tickets()
    {
        return view('user.tickets', [
            'tickets' => HrTicket::where('user_id', auth()->id())->latest()->paginate(20),
        ]);
    }

    public function storeTicket(Request $request)
    {
        HrTicket::create($request->validate([
            'subject' => ['required', 'string', 'max:255'],
            'category' => ['required', 'string', 'max:100'],
            'priority' => ['required', 'string', 'max:50'],
            'message' => ['required', 'string'],
        ]) + ['user_id' => auth()->id(), 'status' => 'open']);

        return back()->with('success', 'HR ticket submitted.');
    }
}
