<?php

namespace App\Http\Controllers;

use App\Models\UtilityFee;
use Illuminate\Http\Request;
use Inertia\Inertia;

class UtilityFeeController extends Controller
{
    public function index(Request $request)
    {
        $query = UtilityFee::query();

        // Search
        if ($request->has('search')) {
            $search = $request->input('search');
            $query->where(function($q) use ($search) {
                $q->where('category', 'like', "%{$search}%")
                  ->orWhere('invoice_number', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        // Filtering
        if ($request->filled('category') && $request->input('category') !== 'all') {
            $query->where('category', $request->input('category'));
        }

        if ($request->filled('date_start')) {
            $query->where('transaction_date', '>=', $request->input('date_start'));
        }

        if ($request->filled('date_end')) {
            $query->where('transaction_date', '<=', $request->input('date_end'));
        }

        // Sorting
        $sortField = $request->input('sort_field');
        $sortDirection = $request->input('sort_direction');

        if ($sortField && $sortDirection) {
            $query->orderBy($sortField, $sortDirection);
        } else {
             $query->orderBy('created_at', 'desc');
        }

        $fees = $query->paginate($request->input('per_page', 10))->withQueryString();

        $availableCategories = UtilityFee::distinct()->pluck('category');

        return Inertia::render('UtilityFee/Index', [
            'fees' => $fees,
            'availableCategories' => $availableCategories,
            'filters' => $request->only(['search', 'category', 'date_start', 'date_end', 'sort_field', 'sort_direction', 'per_page']),
        ]);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'transaction_date' => 'required|date',
            'category' => 'required|string|max:255',
            'amount' => 'required|numeric|min:0',
            'invoice_number' => 'nullable|string|max:255',
            'description' => 'nullable|string',
        ]);

        $fee = UtilityFee::create($validated);

        // Log activity
        activity()
            ->performedOn($fee)
            ->causedBy(auth()->user())
            ->event('created')
            ->withProperties([
                'attributes' => $fee->getAttributes(),
                'snapshot' => [
                    'category' => $fee->category,
                    'amount' => $fee->amount,
                    'transaction_date' => $fee->transaction_date->format('Y-m-d'),
                ]
            ])
            ->log('created');

        return redirect()->back();
    }

    public function update(Request $request, UtilityFee $utility_fee)
    {
        $validated = $request->validate([
            'transaction_date' => 'required|date',
            'category' => 'required|string|max:255',
            'amount' => 'required|numeric|min:0',
            'invoice_number' => 'nullable|string|max:255',
            'description' => 'nullable|string',
        ]);

        // Capture old attributes before update
        $oldAttributes = $utility_fee->getAttributes();

        $utility_fee->update($validated);

        // Capture new attributes
        $newAttributes = $utility_fee->getAttributes();

        // Manual logOnlyDirty: Filter attributes to only include changes
        $changedAttributes = [];
        $changedOldAttributes = [];

        foreach ($newAttributes as $key => $value) {
            // Skip timestamps if they are the only change (optional, but good practice)
            if (in_array($key, ['updated_at'])) continue;

            $oldValue = $oldAttributes[$key] ?? null;
            
            // Simple comparison (casting to string to handle date objects vs strings if necessary, 
            // but Eloquent attributes are usually consistent if casted. 
            // Using loose comparison != handles most cases correctly)
            if ($value != $oldValue) {
                $changedAttributes[$key] = $value;
                $changedOldAttributes[$key] = $oldValue;
            }
        }

        // Only log if there are changes (excluding just updated_at)
        if (empty($changedAttributes)) {
            return redirect()->back();
        }

        // Log activity with before/after comparison
        activity()
            ->performedOn($utility_fee)
            ->causedBy(auth()->user())
            ->event('updated')
            ->withProperties([
                'attributes' => $changedAttributes,
                'old' => $changedOldAttributes,
                'snapshot' => [
                    'category' => $utility_fee->category,
                    'amount' => $utility_fee->amount,
                    'transaction_date' => $utility_fee->transaction_date->format('Y-m-d'),
                ]
            ])
            ->log('updated');

        return redirect()->back();
    }

    public function destroy(UtilityFee $utility_fee)
    {
        // Capture data snapshot before deletion
        $snapshot = [
            'category' => $utility_fee->category,
            'amount' => $utility_fee->amount,
            'transaction_date' => $utility_fee->transaction_date->format('Y-m-d'),
            'invoice_number' => $utility_fee->invoice_number,
            'description' => $utility_fee->description,
        ];

        // Log activity before deletion
        activity()
            ->performedOn($utility_fee)
            ->causedBy(auth()->user())
            ->event('deleted')
            ->withProperties([
                'attributes' => $utility_fee->getAttributes(),
                'snapshot' => $snapshot
            ])
            ->log('deleted');

        $utility_fee->delete();
        
        return redirect()->back();
    }
}
