<?php

namespace App\Http\Controllers;

use App\Models\FixedAsset;
use App\Models\Account;
use App\Models\Supplier;
use App\Models\Bill;
use App\Models\Cashbook;
use App\Models\JournalEntry;
use App\Models\DepreciationLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;

class FixedAssetController extends Controller
{
    /**
     * Display the Asset Register.
     */
    public function index()
    {
        $assets = FixedAsset::where('company_id', Auth::user()->current_company_id)
            ->with(['assetAccount'])
            ->latest()
            ->paginate(15);

        return view('assets.index', compact('assets'));
    }

    /**
     * Show the create form.
     * Simplified to prevent "Undefined Variable" errors.
     */
    public function create()
{
    $companyId = Auth::user()->current_company_id;
    
    // 1. Fetch all accounts for general mapping selects
    $accounts = Account::where('company_id', $companyId)->get();
    
    // 2. Fetch suppliers for the Credit/Bill path
    $suppliers = Supplier::where('company_id', $companyId)->get();
    
    // 3. Filter accounts for the Payment Method dropdown
    // We use 'type' to match the relationship: public function type() in Account.php
    $paymentAccounts = Account::where('company_id', $companyId)
        ->whereHas('type', function($query) {
            $query->whereIn('name', ['Bank', 'Cash', 'Mobile Money']);
        })->get();

    // 4. Fallback: If no Bank/Cash accounts are configured, 
    // provide the full accounts list so the variable is never "undefined"
    if ($paymentAccounts->isEmpty()) {
        $paymentAccounts = $accounts;
    }

    // 5. Explicitly pass the variables to the view
    return view('assets.create', [
        'accounts' => $accounts,
        'suppliers' => $suppliers,
        'paymentAccounts' => $paymentAccounts
    ]);
}

    /**
     * Store asset and handle automated accounting postings.
     */
      public function store(Request $request)
{
    $request->validate([
        'name' => 'required|string|max:255',
        'purchase_date' => 'required|date',
        'purchase_cost' => 'required|numeric',
        'funding_type' => 'required|in:direct,credit',
        'supplier_id' => 'required|exists:suppliers,id', // Now required for both
        'due_date' => 'required_if:funding_type,credit|nullable|date', // New validation
    ]);

    return DB::transaction(function () use ($request) {
        $companyId = Auth::user()->current_company_id;
        $userId = Auth::id();

        // 1. Create Asset
        $asset = FixedAsset::create([
            'company_id' => $companyId,
            'name' => $request->name,
            'asset_number' => 'FA-' . strtoupper(bin2hex(random_bytes(3))),
            'asset_code' => $request->asset_code,
            'purchase_date' => $request->purchase_date,
            'purchase_cost' => $request->purchase_cost,
            'asset_account_id' => $request->asset_account_id,
            'accum_dep_account_id' => $request->accum_dep_account_id,
            'dep_charge_account_id' => $request->dep_charge_account_id,
            'status' => 'active',
            'created_by' => $userId,
        ]);

        $ref = $request->payment_reference ?? 'ACQ-' . $asset->asset_code;

        // 2. Post to Ledger (Debit Asset)
        JournalEntry::create([
            'company_id' => $companyId,
            'account_id' => $request->asset_account_id,
            'transaction_date' => $request->purchase_date,
            'reference' => $ref,
            'description' => "Asset Acquisition: " . $asset->name,
            'debit' => $request->purchase_cost,
            'credit' => 0,
            'user_id' => $userId,
            'transource' => 'Fixed Assets',
            'fixed_assets_id' => $asset->id,
        ]);

        if ($request->funding_type === 'direct') {
            // Path A: Immediate -> Cashbook
            Cashbook::create([
                'company_id' => $companyId,
                'supplier_id' => $request->supplier_id, // Saved even for cash
                'cash_bank_account_id' => $request->credit_account_id,
                'corresponding_account_id' => $request->asset_account_id,
                'fixed_assets_id' => $asset->id,
                'reference' => $ref,
                'payment_method' => 'Direct',
                'credit' => $request->purchase_cost,
                'transaction_date' => $request->purchase_date,
                'memo' => "Direct Purchase: " . $asset->name,
                'created_by' => $userId,
            ]);
            // (Include Credit Journal Entry here for Bank/Cash)
        } else {
            // Path B: Credit -> Bill
            Bill::create([
                'company_id' => $companyId,
                'supplier_id' => $request->supplier_id,
                'bill_date' => $request->purchase_date,
                'due_date' => $request->due_date, // User defined due date
                'bill_no' => $ref,
                'total_amount' => $request->purchase_cost,
                'outstanding_balance' => $request->purchase_cost,
                'status' => 'unpaid',
                'fixed_assets_id' => $asset->id,
                'memo' => "Credit Purchase: " . $asset->name,
                'terms' => 'Credit',
                'created_by' => $userId,
            ]);
            // (Include Credit Journal Entry here for Accounts Payable)
        }

        return redirect()->route('assets.index')->with('success', 'Asset capitalized successfully.');
    });
}

    /**
     * Depreciation Engine.
     */
    public function runDepreciation(Request $request)
    {
        $date = Carbon::parse($request->date ?? now())->endOfMonth();
        $companyId = Auth::user()->current_company_id;

        return DB::transaction(function () use ($date, $companyId) {
            $assets = FixedAsset::where('company_id', $companyId)
                ->where('status', 'active')
                ->get();

            $processedCount = 0;

            foreach ($assets as $asset) {
                $monthlyDep = ($asset->purchase_cost - $asset->salvage_value) / $asset->useful_life_months;
                $totalDepreciated = DepreciationLog::where('fixed_asset_id', $asset->id)->sum('depreciation_amount');
                $remainingValue = $asset->purchase_cost - $totalDepreciated;

                if ($remainingValue <= $asset->salvage_value) {
                    $asset->update(['status' => 'fully_depreciated']);
                    continue;
                }

                $chargeAmount = min($monthlyDep, $remainingValue - $asset->salvage_value);
                $ref = 'DEP-' . $date->format('Ym') . '-' . $asset->id;
                
                // DEBIT Expense
                JournalEntry::create([
                    'company_id' => $companyId,
                    'account_id' => $asset->dep_charge_account_id,
                    'transaction_date' => $date,
                    'reference' => $ref,
                    'description' => "Depreciation: " . $asset->name,
                    'debit' => $chargeAmount,
                    'credit' => 0,
                    'user_id' => Auth::id(),
                    'transource' => 'Fixed Assets',
                    'fixed_assets_id' => $asset->id,
                ]);

                // CREDIT Accumulated
                JournalEntry::create([
                    'company_id' => $companyId,
                    'account_id' => $asset->accum_dep_account_id,
                    'transaction_date' => $date,
                    'reference' => $ref,
                    'description' => "Depreciation: " . $asset->name,
                    'debit' => 0,
                    'credit' => $chargeAmount,
                    'user_id' => Auth::id(),
                    'transource' => 'Fixed Assets',
                    'fixed_assets_id' => $asset->id,
                ]);

                DepreciationLog::create([
                    'company_id' => $companyId,
                    'fixed_asset_id' => $asset->id,
                    'transaction_date' => $date,
                    'depreciation_amount' => $chargeAmount,
                    'book_value_after' => $remainingValue - $chargeAmount,
                    'created_by' => Auth::id(),
                ]);

                $processedCount++;
            }

            return back()->with('success', "Processed $processedCount assets.");
        });
    }

    public function assetSchedule(Request $request)
    {
        $companyId = Auth::user()->current_company_id;
        $date = $request->date ?? now()->format('Y-m-d');

        $assets = FixedAsset::where('company_id', $companyId)
            ->with(['depreciationLogs' => function($query) use ($date) {
                $query->where('transaction_date', '<=', $date);
            }])
            ->get()
            ->map(function($asset) {
                $asset->total_depreciation = $asset->depreciationLogs->sum('depreciation_amount');
                $asset->nbv = $asset->purchase_cost - $asset->total_depreciation;
                return $asset;
            });

        return view('assets.asset-schedule', compact('assets', 'date'));
    }
}