<?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\Http\Request;
use Carbon\Carbon;

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

    public function index()
    {
        $user = auth()->user();

        // Base query with relationships
        $query = Claim::with(['project', 'jenisKenderaan'])->latest();

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

        $claims = $query->get();

        // Group by month-year (example: "2025-10")
        $claimsByMonth = $claims->groupBy(function($claim) {
            return \Carbon\Carbon::parse($claim->claim_date)->format('F Y'); // "October 2025"
        });

        $projects = Project::all();
        $jenisKenderaan = JenisKenderaan::all();

        return view('mileage::application.index', compact('claimsByMonth', 'projects', 'jenisKenderaan'));
    }

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

        // calculation logic
        $claimableMileage = max(0, $validated['total_mileage'] - 40);

        if ($validated['jenis_kenderaan_id'] == 1) { // Car
            $rate = $claimableMileage <= 500 ? 0.55 : 0.50;
        } else {
            $rate = 0.30;
        }

        $calculatedAmount = $claimableMileage * $rate;
        $calculatedAmount += floatval($validated['toll_amount'] ?? 0);
        $calculatedAmount += floatval($validated['others_amount'] ?? 0);

        $validated['calculated_amount'] = $calculatedAmount;
        $validated['claimable_mileage'] = $claimableMileage;

        // penalty calculation using DAYS (submission time = now)
        $claimDate = Carbon::parse($validated['claim_date']);
        $submissionDate = Carbon::now();
        $daysDiff = $claimDate->diffInDays($submissionDate);

        if ($daysDiff <= 30) {
            $penalty = 0;
            $penaltyReason = 'Tiada penalti (≤ 1 bulan)';
        } elseif ($daysDiff <= 90) { // >30 && <=90
            $penalty = $calculatedAmount * 0.10;
            $penaltyReason = 'Lewat hantar lebih 1 bulan tetapi ≤ 3 bulan (10%)';
        } elseif ($daysDiff <= 180) { // >90 && <=180
            $penalty = $calculatedAmount * 0.30;
            $penaltyReason = 'Lewat hantar lebih 3 bulan tetapi ≤ 6 bulan (30%)';
        } else { // >180
            $penalty = 0; // no numeric penalty applied automatically
            $penaltyReason = 'Lewat lebih 6 bulan - Tertakluk kepada budi bicara BOD';
        }

        $validated['penalty_amount'] = $penalty;
        $validated['penalty_reason'] = $penaltyReason;
        $validated['total_claim_amount'] = $calculatedAmount - $penalty;

        // default status
        $validated['status'] = 'Diproses';

        // create
        $claim = Claim::create($validated);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Claim submitted successfully!',
                'claim'   => $claim->load(['project', 'jenisKenderaan']),
            ]);
        }

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

        // decide new status based on role (if you want automated transitions)
        $newStatus = null;
        if (auth()->check()) {
            if (auth()->user()->hasRole('Project Manager')) {
                $newStatus = 'Disokong';
            } elseif (auth()->user()->hasRole('HOD')) {
                $newStatus = 'Disokong';
            } elseif (auth()->user()->hasRole('Project Director')) {
                $newStatus = 'Disahkan';
            } elseif (auth()->user()->hasRole('Finance')) {
                $newStatus = 'Disemak';
            } elseif (auth()->user()->hasRole('Finance Director')) {
                $newStatus = 'Diluluskan';
            }
        }

        $validated = $request->validate([
            'user_id'               => 'required',
            'claim_date'            => 'required|date',
            'jenis_kenderaan_id'    => 'required|exists:lkp_jenis_kenderaans,id',
            'project_id'            => 'required|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',
        ]);

        // calculation logic (same as store)
        $claimableMileage = max(0, $validated['total_mileage'] - 40);

        if ($validated['jenis_kenderaan_id'] == 1) {
            $rate = $claimableMileage <= 500 ? 0.55 : 0.50;
        } else {
            $rate = 0.30;
        }

        $calculatedAmount = $claimableMileage * $rate;
        $calculatedAmount += floatval($validated['toll_amount'] ?? 0);
        $calculatedAmount += floatval($validated['others_amount'] ?? 0);

        $validated['calculated_amount'] = $calculatedAmount;
        $validated['claimable_mileage'] = $claimableMileage;

        // penalty calculation using DAYS (submission time = now)
        $claimDate = Carbon::parse($validated['claim_date']);
        $submissionDate = Carbon::now();
        $daysDiff = $claimDate->diffInDays($submissionDate);

        if ($daysDiff <= 30) {
            $penalty = 0;
            $penaltyReason = 'Tiada penalti (≤ 1 bulan)';
        } elseif ($daysDiff <= 90) {
            $penalty = $calculatedAmount * 0.10;
            $penaltyReason = 'Lewat hantar >1 ≤3 bulan (10%)';
        } elseif ($daysDiff <= 180) {
            $penalty = $calculatedAmount * 0.30;
            $penaltyReason = 'Lewat hantar >3 ≤6 bulan (30%)';
        } else {
            $penalty = 0;
            $penaltyReason = 'Tertakluk kepada BOD';
        }

        $validated['penalty_amount'] = $penalty;
        $validated['penalty_reason'] = $penaltyReason;
        $validated['total_claim_amount'] = $calculatedAmount - $penalty;

        // apply automated status change if applicable
        if ($newStatus) {
            $validated['status'] = $newStatus;
        }

        // update
        $claim->update($validated);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Claim updated successfully!',
                'claim'   => $claim->load(['project', 'jenisKenderaan']),
            ]);
        }

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

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

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

    public function show($id)
    {
        // load claim
        $claim = Claim::with(['project', 'jenisKenderaan'])->findOrFail($id);

        // Recompute penalty for display based on actual submission date (created_at)
        // so show page always displays correct reason even if saved earlier incorrectly.
        $claimDate = Carbon::parse($claim->claim_date);
        $submissionDate = $claim->created_at ?? Carbon::now();
        $daysDiff = $claimDate->diffInDays($submissionDate);

        $calculatedAmount = $claim->calculated_amount ?? 0;

        if ($daysDiff <= 30) {
            $displayPenalty = 0;
            $displayReason = 'Tiada penalti (≤ 1 bulan)';
        } elseif ($daysDiff <= 90) {
            $displayPenalty = $calculatedAmount * 0.10;
            $displayReason = 'Lewat hantar >1 ≤3 bulan (10%)';
        } elseif ($daysDiff <= 180) {
            $displayPenalty = $calculatedAmount * 0.30;
            $displayReason = 'Lewat hantar >3 ≤6 bulan (30%)';
        } else {
            $displayPenalty = 0;
            $displayReason = 'Tertakluk kepada BOD';
        }

        // Attach computed display-only properties (won't persist to DB)
        $claim->display_penalty_amount = $displayPenalty;
        $claim->display_penalty_reason = $displayReason;
        $claim->display_total_claim_amount = ($calculatedAmount - $displayPenalty);

        return view('mileage::application.show', 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';
                break;

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

            case 'review': // Accounting
                $claim->status = 'Disemak';
                break;

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

            case 'reject': // Any approver
                $claim->status = 'Ditolak';
                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);
    }

}
