<?php

namespace Portal\Mileage\Http\Controllers;

use Portal\Mileage\Model\Users;
use Portal\Mileage\Model\Project;
use Portal\Mileage\Model\JenisKenderaan;
use Portal\Mileage\Model\Claim;

use Illuminate\Routing\Controller;
use Illuminate\Support\Collection;
use Illuminate\Http\Request;
use Carbon\Carbon;

class ApplicationsController extends Controller
{
    public function __construct()
    {
        //
    }

    public function index(Request $request)
    {
        $user = auth()->user();
        $filter = $request->get('filter'); // ?filter=with or without
        $month = $request->get('month', Carbon::now()->format('Y-m')); // e.g., 2025-10

        // Parse month & year
        $parsedMonth = Carbon::createFromFormat('Y-m', $month);
        $monthNum = $parsedMonth->month;
        $yearNum = $parsedMonth->year;

        // Base query: user's claims within selected month
        $query = Claim::with(['project', 'jenisKenderaan', 'user'])
            ->where('user_id', $user->id)
            ->whereMonth('claim_date', $monthNum)
            ->whereYear('claim_date', $yearNum)
            ->latest();

        // Apply filter (with / without project)
        if ($filter === 'with') {
            $query->whereNotNull('project_id');
        } elseif ($filter === 'without') {
            $query->whereNull('project_id');
        }

        // Restrict for Project Manager (see only their project claims)
        if ($user->managedProjects()->exists()) {
            $projectIds = $user->managedProjects()->pluck('fk_project_id');
            $query->whereIn('project_id', $projectIds);
        }

        $claims = $query->get();

        // Load supporting dropdown data
        $projects = Project::all();
        $jenisKenderaan = JenisKenderaan::all();

        // Pass all to view
        return view('mileage::application.index', [
            'claims' => $claims,
            'projects' => $projects,
            'jenisKenderaan' => $jenisKenderaan,
            'month' => $month,
            'filter' => $filter,
        ]);
    }

    public function store(Request $request)
    {
        // Validate request data
        $validated = $request->validate([
            'claim_date'            => 'required|date',
            'jenis_kenderaan_id'    => 'required|exists:lkp_jenis_kenderaans,id',
            'project_id'            => 'nullable|exists:lkp_project,id',
            'description'           => 'required',
            'distance_from'         => 'nullable',
            'distance_to'           => 'nullable',
            'total_mileage'         => 'required|numeric',
            'toll_amount'           => 'nullable|numeric',
            'others_amount'         => 'nullable|numeric',
            'others_description'    => 'nullable|string|max:255',
        ]);

        $validated['user_id'] = auth()->id();  // Get the current authenticated user

        // Calculate the total claim amount and mileage
        $calculatedAmount = $this->calculateClaimAmount($validated);
        $validated['calculated_amount'] = $calculatedAmount;

        // Handle the status based on actions (e.g., project manager, director, finance)
        $validated['status'] = 'Diproses'; // Initial status
        
        // Store the claim in the database
        $claim = Claim::create($validated);

        // Now, we need to manage the role and verify the project

        // Example: If project_id is set, link the claim with the project and handle roles
        if ($claim->project) {
            $project = $claim->project;

            // Here, you can check if the claim should be verified by a Project Manager (HOD)
            // For now, we’re assuming you use the role directly to set verified_by
            if ($project->project_manager_id) {
                $claim->verified_by = $project->project_manager_id;
            }

            // Similarly, you can handle who approves and reviews (e.g., Project Director or BOD)
            if ($project->project_director_id) {
                $claim->approved_by = $project->project_director_id;
            }

            $claim->save();
        }

        return redirect()->route('mileage::applications.index')->with('success', 'Claim submitted successfully!');
    }

    public function edit($id)
    {
        $claim = Claim::findOrFail($id);
        $projects = \Portal\Mileage\Model\Project::all();
        $jenisKenderaan = \Portal\Mileage\Model\JenisKenderaan::all();

        return view('mileage::applications.edit', compact('claim','projects','jenisKenderaan'));
    }

    public function update(Request $request, $id)
    {
        $claim = Claim::findOrFail($id);

        // Check if any required DB fields are null before allowing update
        $requiredFields = [
            'claim_date',
            'distance_from',
            'distance_to',
            'description',
            'total_mileage'
        ];

        foreach ($requiredFields as $field) {
            if (is_null($claim->$field) || $claim->$field === '') {
                return redirect()->back()->with('error', 'Tidak boleh simpan kerana maklumat tuntutan asal tidak lengkap.');
            }
        }

        // Validate new input before updating
        $request->validate([
            'claim_date' => 'required|date',
            'distance_from' => 'required|string',
            'distance_to' => 'required|string',
            'description' => 'required|string',
            'total_mileage' => 'required|numeric|min:0',
            'toll_amount' => 'nullable|numeric|min:0',
            'others_amount' => 'nullable|numeric|min:0',
            'others_details' => 'required_if:others_amount,>,0|string|nullable',
        ]);

        // If claim data is valid, update it
        $claim->update([
            'claim_date' => $request->claim_date,
            'distance_from' => $request->distance_from,
            'distance_to' => $request->distance_to,
            'description' => $request->description,
            'total_mileage' => $request->total_mileage,
            'toll_amount' => $request->toll_amount,
            'others_amount' => $request->others_amount,
            'others_details' => $request->others_details,
        ]);

        return redirect()->back()->with('success', 'Tuntutan berjaya dikemaskini.');
    }

    public function destroy($id)
    {
        $claim = Claim::findOrFail($id);
        $claim->delete();

        return redirect()->route('mileage::applications.index')->with('success', 'Claim deleted successfully!');
    }

    public function show(Request $request, $id)
    {
        $claim = Claim::with(['project', 'jenisKenderaan', 'user'])->findOrFail($id);
        $month = Carbon::parse($claim->claim_date)->format('Y-m');
        $userId = $claim->user_id;
        $projectId = $request->get('project_id', $claim->project_id);

        $query = Claim::with(['project', 'jenisKenderaan'])
            ->where('user_id', $userId)
            ->whereYear('claim_date', Carbon::parse($claim->claim_date)->year)
            ->whereMonth('claim_date', Carbon::parse($claim->claim_date)->month);

        if ($projectId) {
            $query->where('project_id', $projectId);
        } else {
            $query->whereNull('project_id');
        }

        $claims = $query->orderBy('claim_date', 'asc')->get();

        $totalMileage = $claims->sum('total_mileage');
        $totalToll = $claims->sum('toll_amount');
        $totalOthers = $claims->sum('others_amount');
        $totalAmount = $claims->sum('total_claim_amount');
        $projectName = $claims->first()->project->p_project_description ?? 'Tanpa Projek';

        return view('mileage::application.show', compact(
            'claims', 'claim', 'projectName', 'totalMileage', 'totalToll', 'totalOthers', 'totalAmount', 'month'
        ));
    }

    /**
     * Show a single claim (HR detailed view)
     */
    public function viewEach($id)
    {
        $claim = Claim::with(['project', 'jenisKenderaan'])->findOrFail($id);
        return view('mileage.applications.viewEach', compact('claim'));
    }

    public function updateStatus(Request $request, $id)
    {
        $claim = Claim::findOrFail($id);
        $user = auth()->user();

        switch ($request->action) {
            case 'verify': // PM/HOD
                $claim->status = 'Disokong';
                $claim->approved_by = $user->id;
                break;

            case 'approve': // PD/BOD
                $claim->status = 'Disahkan';
                $claim->approved_by = $user->id;
                break;

            case 'review': // Finance
                $claim->status = 'Disemak';
                $claim->approved_by = $user->id;
                break;

            case 'finance_approve': // Finance Director
                $claim->status = 'Diluluskan';
                $claim->approved_by = $user->id;
                break;

            case 'reject': // Any approver
                $claim->status = 'Ditolak';
                $claim->rejected_by = $user->id;
                break;

            case 'amend': // Finance edits
                $claim->status = 'Dibetulkan';
                break;

            case 'pay': // Final finance step
                $claim->status = 'Dibayar';
                break;
        }

        $claim->save();

        return back()->with('success', 'Claim status updated to ' . $claim->status);
    }


}
