<?php

namespace App\Http\Controllers;

use App\Models\Account;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;

class AccountController extends Controller
{
    /**
     * Display a listing of accounts.
     */
    public function index(Request $request): View
    {
        $query = Account::query();

        // Filter by type
        if ($request->filled('type')) {
            $query->where('type', $request->type);
        }

        // Filter by sub_type
        if ($request->filled('sub_type')) {
            $query->where('sub_type', $request->sub_type);
        }

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%");
            });
        }

        // Only active
        if ($request->boolean('active_only', true)) {
            $query->active();
        }

        $accounts = $query->orderBy('code')->get();

        // Group by type for display
        $groupedAccounts = $accounts->groupBy('type');

        $types = Account::TYPES;
        $subTypes = Account::SUB_TYPES;

        return view('accounts.index', compact('accounts', 'groupedAccounts', 'types', 'subTypes'));
    }

    /**
     * Show the form for creating a new account.
     */
    public function create(): View
    {
        $types = Account::TYPES;
        $subTypes = Account::SUB_TYPES;
        $parentAccounts = Account::active()->orderBy('code')->get();
        $nextCode = '';

        return view('accounts.create', compact('types', 'subTypes', 'parentAccounts', 'nextCode'));
    }

    /**
     * Store a newly created account.
     */
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'code' => 'required|string|max:20|unique:accounts,code',
            'name' => 'required|string|max:100',
            'type' => 'required|in:asset,liability,equity,income,expense',
            'sub_type' => 'nullable|string',
            'parent_id' => 'nullable|exists:accounts,id',
            'opening_balance' => 'nullable|numeric|min:0',
            'opening_type' => 'nullable|in:debit,credit',
            'description' => 'nullable|string|max:255',
        ]);

        $validated['opening_balance'] = $validated['opening_balance'] ?? 0;
        $validated['opening_type'] = $validated['opening_type'] ?? 'debit';
        $validated['current_balance'] = $validated['opening_balance'];
        $validated['is_active'] = true;

        Account::create($validated);

        return redirect()->route('accounts.index')
            ->with('success', 'Account created successfully.');
    }

    /**
     * Display the specified account.
     */
    public function show(Account $account): View
    {
        $account->load('parent', 'children', 'transactions');
        
        return view('accounts.show', compact('account'));
    }

    /**
     * Show the form for editing the specified account.
     */
    public function edit(Account $account): View
    {
        $types = Account::TYPES;
        $subTypes = Account::SUB_TYPES;
        $parentAccounts = Account::active()
            ->where('id', '!=', $account->id)
            ->orderBy('code')
            ->get();

        return view('accounts.edit', compact('account', 'types', 'subTypes', 'parentAccounts'));
    }

    /**
     * Update the specified account.
     */
    public function update(Request $request, Account $account): RedirectResponse
    {
        $validated = $request->validate([
            'code' => 'required|string|max:20|unique:accounts,code,' . $account->id,
            'name' => 'required|string|max:100',
            'type' => 'required|in:asset,liability,equity,income,expense',
            'sub_type' => 'nullable|string',
            'parent_id' => 'nullable|exists:accounts,id',
            'opening_balance' => 'nullable|numeric|min:0',
            'opening_type' => 'nullable|in:debit,credit',
            'description' => 'nullable|string|max:255',
            'is_active' => 'boolean',
        ]);

        $validated['is_active'] = $request->boolean('is_active', true);

        $account->update($validated);

        // Recalculate balance if opening balance changed
        $account->updateBalance();

        return redirect()->route('accounts.index')
            ->with('success', 'Account updated successfully.');
    }

    /**
     * Remove the specified account.
     */
    public function destroy(Account $account): RedirectResponse
    {
        // Check if account is system account
        if ($account->is_system) {
            return redirect()->route('accounts.index')
                ->with('error', 'System accounts cannot be deleted.');
        }

        // Check if account has transactions
        if ($account->transactions()->exists()) {
            return redirect()->route('accounts.index')
                ->with('error', 'Cannot delete account with transactions. Deactivate it instead.');
        }

        // Check if account has child accounts
        if ($account->children()->exists()) {
            return redirect()->route('accounts.index')
                ->with('error', 'Cannot delete account with sub-accounts.');
        }

        $account->delete();

        return redirect()->route('accounts.index')
            ->with('success', 'Account deleted successfully.');
    }

    /**
     * Get next code via AJAX
     */
    public function getNextCode(Request $request)
    {
        $type = $request->get('type', 'asset');
        $code = Account::generateCode($type);

        return response()->json(['code' => $code]);
    }

    /**
     * Get sub-types via AJAX
     */
    public function getSubTypes(Request $request)
    {
        $type = $request->get('type', 'asset');
        $subTypes = Account::SUB_TYPES[$type] ?? [];

        return response()->json($subTypes);
    }
}
