<?php

namespace App\Http\Controllers;

use App\Models\Account;
use App\Models\Organization;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AccountController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:accounts.view')->only(['index', 'show']);
        $this->middleware('permission:accounts.create')->only(['create', 'store']);
        $this->middleware('permission:accounts.edit')->only(['edit', 'update']);
        $this->middleware('permission:accounts.delete')->only(['destroy']);
    }

    protected function getOrganizationScope()
    {
        $user = Auth::user();
        if ($user->hasRole('Super Admin')) {
            return null;
        }
        $orgIds = collect([$user->organization_id]);
        $this->getChildOrganizations($user->organization_id, $orgIds);
        return $orgIds->toArray();
    }

    protected function getChildOrganizations($parentId, &$orgIds)
    {
        $children = Organization::where('parent_id', $parentId)->pluck('id');
        foreach ($children as $childId) {
            $orgIds->push($childId);
            $this->getChildOrganizations($childId, $orgIds);
        }
    }

    public function index(Request $request)
    {
        $query = Account::with('organization');
        $scope = $this->getOrganizationScope();
        if ($scope !== null) {
            $query->whereIn('organization_id', $scope);
        }

        if ($request->filled('search')) {
            $query->where('name', 'like', "%{$request->search}%");
        }

        $accounts = $query->orderBy('name')->paginate(15)->withQueryString();

        return view('finance.accounts.index', compact('accounts'));
    }

    public function create()
    {
        $scope = $this->getOrganizationScope();
        $organizations = Organization::query();
        if ($scope !== null) {
            $organizations->whereIn('id', $scope);
        }
        $organizations = $organizations->orderBy('name')->get();

        return view('finance.accounts.create', compact('organizations'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'organization_id' => 'required|exists:organizations,id',
            'name' => 'required|string|max:255',
            'type' => 'required|in:Bank,Mobile,Cash',
            'currency' => 'required|string|max:10',
        ]);

        $scope = $this->getOrganizationScope();
        if ($scope !== null && !in_array($validated['organization_id'], $scope)) {
            abort(403);
        }

        $validated['balance'] = 0;
        Account::create($validated);

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

    public function edit(Account $account)
    {
        $scope = $this->getOrganizationScope();
        if ($scope !== null && !in_array($account->organization_id, $scope)) {
            abort(403);
        }

        $organizations = Organization::query();
        if ($scope !== null) {
            $organizations->whereIn('id', $scope);
        }
        $organizations = $organizations->orderBy('name')->get();

        return view('finance.accounts.edit', compact('account', 'organizations'));
    }

    public function update(Request $request, Account $account)
    {
        $scope = $this->getOrganizationScope();
        if ($scope !== null && !in_array($account->organization_id, $scope)) {
            abort(403);
        }

        $validated = $request->validate([
            'organization_id' => 'required|exists:organizations,id',
            'name' => 'required|string|max:255',
            'type' => 'required|in:Bank,Mobile,Cash',
            'currency' => 'required|string|max:10',
        ]);

        $account->update($validated);

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

    public function destroy(Account $account)
    {
        $scope = $this->getOrganizationScope();
        if ($scope !== null && !in_array($account->organization_id, $scope)) {
            abort(403);
        }

        if ($account->transactions()->exists()) {
            return back()->with('error', 'Cannot delete account with existing transactions.');
        }

        $account->delete();

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