<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\BackOfficeTransaction;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;

class BackOfficeIncomeController extends Controller
{
    /**
     * Display a listing of incomes
     * 
     * @param Request $request
     * @return \Illuminate\View\View
     */
    public function index(Request $request)
    {
        // Query builder
        $query = BackOfficeTransaction::income()
            ->with('creator')
            ->latest('transaction_date');

        // Filter by date range - perbaiki agar bisa filter hanya start_date atau end_date saja
        if ($request->filled('start_date')) {
            $query->whereDate('transaction_date', '>=', $request->start_date);
        }
        if ($request->filled('end_date')) {
            $query->whereDate('transaction_date', '<=', $request->end_date);
        }

        // Filter by category
        if ($request->filled('category') && $request->category !== '') {
            $query->byCategory($request->category);
        }

        // Search by description or reference number - perbaiki dengan trim
        if ($request->filled('search') && trim($request->search) !== '') {
            $query->search(trim($request->search));
        }

        // Pagination
        $itemsPerPage = (int) Setting::get('items_per_page', 10);
        $incomes = $query->paginate($itemsPerPage)->withQueryString();

        // Calculate total income (with filters applied)
        $totalIncome = $query->sum('amount');

        // Get categories for filter dropdown
        $categories = BackOfficeTransaction::$incomeCategories;

        return view('admin.backoffice.income.index', compact(
            'incomes',
            'totalIncome',
            'categories'
        ));
    }

    /**
     * Show the form for creating a new income
     * 
     * @return \Illuminate\View\View
     */
    public function create()
    {
        $categories = BackOfficeTransaction::$incomeCategories;

        return view('admin.backoffice.income.create', compact('categories'));
    }

    /**
     * Store a newly created income in database
     * 
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request)
    {
        // Validation
        $validated = $request->validate([
            'category' => 'required|string|max:50',
            'description' => 'required|string|max:255',
            'amount' => 'required|numeric|min:0|max:999999999999.99',
            'transaction_date' => 'required|date',
            'reference_number' => 'nullable|string|max:100',
            'notes' => 'nullable|string|max:1000',
            'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:2048', // Max 2MB
        ], [
            'category.required' => 'Kategori harus dipilih',
            'description.required' => 'Deskripsi harus diisi',
            'amount.required' => 'Jumlah harus diisi',
            'amount.numeric' => 'Jumlah harus berupa angka',
            'amount.min' => 'Jumlah tidak boleh negatif',
            'transaction_date.required' => 'Tanggal transaksi harus diisi',
            'attachment.mimes' => 'File harus berformat JPG, PNG, atau PDF',
            'attachment.max' => 'Ukuran file maksimal 2MB',
        ]);

        DB::beginTransaction();
        try {
            // Set type as income
            $validated['type'] = 'income';
            $validated['created_by'] = Auth::id();

            // Handle file upload
            if ($request->hasFile('attachment')) {
                $file = $request->file('attachment');
                $filename = time() . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '', $file->getClientOriginalName());
                $validated['attachment'] = $file->storeAs('backoffice/income', $filename, 'uploads');
            }

            // Create transaction
            $income = BackOfficeTransaction::create($validated);

            DB::commit();

            return redirect()
                ->route('admin.backoffice.income.index')
                ->with('success', 'Data pemasukan berhasil ditambahkan!');
        } catch (\Exception $e) {
            DB::rollBack();

            // Delete uploaded file if error
            if (isset($validated['attachment'])) {
                Storage::disk('public')->delete($validated['attachment']);
            }

            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'Gagal menambahkan pemasukan: ' . $e->getMessage());
        }
    }

    /**
     * Display the specified income
     * 
     * @param int $id
     * @return \Illuminate\View\View
     */
    public function show($id)
    {
        $income = BackOfficeTransaction::income()
            ->with('creator')
            ->findOrFail($id);

        return view('admin.backoffice.income.show', compact('income'));
    }

    /**
     * Show the form for editing the specified income
     * 
     * @param int $id
     * @return \Illuminate\View\View
     */
    public function edit($id)
    {
        $income = BackOfficeTransaction::income()->findOrFail($id);
        $categories = BackOfficeTransaction::$incomeCategories;

        return view('admin.backoffice.income.edit', compact('income', 'categories'));
    }

    /**
     * Update the specified income in database
     * 
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(Request $request, $id)
    {
        $income = BackOfficeTransaction::income()->findOrFail($id);

        // Validation
        $validated = $request->validate([
            'category' => 'required|string|max:50',
            'description' => 'required|string|max:255',
            'amount' => 'required|numeric|min:0|max:999999999999.99',
            'transaction_date' => 'required|date',
            'reference_number' => 'nullable|string|max:100',
            'notes' => 'nullable|string|max:1000',
            'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:2048',
        ], [
            'category.required' => 'Kategori harus dipilih',
            'description.required' => 'Deskripsi harus diisi',
            'amount.required' => 'Jumlah harus diisi',
            'amount.numeric' => 'Jumlah harus berupa angka',
            'amount.min' => 'Jumlah tidak boleh negatif',
            'transaction_date.required' => 'Tanggal transaksi harus diisi',
            'attachment.mimes' => 'File harus berformat JPG, PNG, atau PDF',
            'attachment.max' => 'Ukuran file maksimal 2MB',
        ]);

        DB::beginTransaction();
        try {
            // Handle file upload
            if ($request->hasFile('attachment')) {
                // Delete old file
                if ($income->attachment) {
                    Storage::disk('public')->delete($income->attachment);
                }

                $file = $request->file('attachment');
                $filename = time() . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '', $file->getClientOriginalName());
                $validated['attachment'] = $file->storeAs('backoffice/income', $filename, 'uploads');
            }

            // Update transaction
            $income->update($validated);

            DB::commit();

            return redirect()
                ->route('admin.backoffice.income.index')
                ->with('success', 'Data pemasukan berhasil diperbarui!');
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'Gagal memperbarui pemasukan: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified income from database
     * 
     * @param int $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy($id)
    {
        $income = BackOfficeTransaction::income()->findOrFail($id);

        DB::beginTransaction();
        try {
            // Delete attachment file if exists
            if ($income->attachment) {
                Storage::disk('public')->delete($income->attachment);
            }

            // Soft delete the transaction
            $income->delete();

            DB::commit();

            return redirect()
                ->route('admin.backoffice.income.index')
                ->with('success', 'Data pemasukan berhasil dihapus!');
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()
                ->back()
                ->with('error', 'Gagal menghapus pemasukan: ' . $e->getMessage());
        }
    }
}
