<?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\Support\Facades\Auth;
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)
    {
        // your existing store logic
        $calculation = $this->calculateClaimAmount($request);

        Claim::create([
            'user_id' => Auth::id(),
            'project_id' => $request->project_id,
            'claim_date' => $request->claim_date,
            'jenis_kenderaan_id' => $request->jenis_kenderaan_id,
            'description' => $request->description,
            'distance_from' => $request->distance_from,
            'distance_to' => $request->distance_to,
            'total_mileage' => $request->total_mileage,
            'toll_amount' => $request->toll_amount ?? 0,
            'others_amount' => $request->others_amount ?? 0,
            'claimable_mileage' => $calculation['claimable_mileage'],
            'rate' => $calculation['rate'],
            'mileage_amount' => $calculation['mileage_amount'],
            'total_claim_amount' => $calculation['total_claim'],
            'status' => 'Diproses',
        ]);

        return redirect()->route('mileage::applications.index')
            ->with('success', 'Tuntutan berjaya dihantar!');
    }

    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);

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

        // Calculate new claim amount using same logic as store()
        $totalMileage = (float) $request->total_mileage;
        $toll = (float) ($request->toll_amount ?? 0);
        $others = (float) ($request->others_amount ?? 0);

        // Deduct first 40km
        $claimableMileage = $totalMileage > 40 ? $totalMileage - 40 : 0;

        // Apply rate logic (same as store)
        $rate = $claimableMileage > 500 ? 0.50 : 0.55;
        $mileageAmount = $claimableMileage * $rate;
        $totalClaim = $mileageAmount + $toll + $others;

        // Update the record
        $claim->update([
            'claim_date' => $request->claim_date,
            'distance_from' => $request->distance_from,
            'distance_to' => $request->distance_to,
            'description' => $request->description,
            'total_mileage' => $totalMileage,
            'toll_amount' => $toll,
            'others_amount' => $others,
            'others_details' => $request->others_details,
            'claimable_mileage' => $claimableMileage,
            'rate' => $rate,
            'mileage_amount' => $mileageAmount,
            'total_claim_amount' => $totalClaim,
        ]);

        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);
    }

    private function calculateClaimAmount($request)
    {
        $totalMileage = (float) $request->total_mileage;
        $toll = (float) $request->toll_amount;
        $others = (float) $request->others_amount;

        // Deduct first 40km
        $claimableMileage = $totalMileage > 40 ? $totalMileage - 40 : 0;

        // Apply rate logic
        $rate = $claimableMileage > 500 ? 0.50 : 0.55;
        $mileageAmount = $claimableMileage * $rate;
        $totalClaim = $mileageAmount + $toll + $others;

        return [
            'claimable_mileage' => $claimableMileage,
            'rate' => $rate,
            'mileage_amount' => $mileageAmount,
            'total_claim' => $totalClaim,
        ];
    }

}
