<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\BankAccount;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class BankAccountController extends Controller
{
    public function index(Request $request)
    {
        $user = $request->user();
        
        // Super Admin can fetch bank accounts for any company
        $companyId = $user->isSuperAdmin() && $request->filled('company_id')
            ? $request->company_id
            : $user->company_id;
        
        $query = BankAccount::with('company')->where('company_id', $companyId);

        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

        $accounts = $query->latest()->get();
        return response()->json(['data' => $accounts]);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        
        $validated = $request->validate([
            'account_name' => 'required|string|max:255',
            'bank_name' => 'required|string|max:255',
            'account_number' => 'required|string|max:50|unique:bank_accounts,account_number',
            'account_type' => 'required|in:current,savings,domiciliary',
            'currency' => 'required|string|max:3',
            'opening_balance' => 'required|numeric|min:0',
            'is_primary' => 'boolean',
            'notes' => 'nullable|string',
        ]);

        $account = BankAccount::create([
            'company_id' => $user->company_id,
            'account_name' => $validated['account_name'],
            'bank_name' => $validated['bank_name'],
            'account_number' => $validated['account_number'],
            'account_type' => $validated['account_type'],
            'currency' => $validated['currency'],
            'opening_balance' => $validated['opening_balance'],
            'current_balance' => $validated['opening_balance'],
            'is_primary' => $validated['is_primary'] ?? false,
            'notes' => $validated['notes'] ?? null,
        ]);

        return response()->json(['data' => $account->load('company'), 'message' => 'Bank account created successfully'], 201);
    }

    public function show($id)
    {
        $user = $request->user();
        $account = BankAccount::with('company')->where('company_id', $user->company_id)->findOrFail($id);
        return response()->json(['data' => $account]);
    }

    public function update(Request $request, $id)
    {
        $user = $request->user();
        $account = BankAccount::where('company_id', $user->company_id)->findOrFail($id);

        $validated = $request->validate([
            'account_name' => 'sometimes|string|max:255',
            'bank_name' => 'sometimes|string|max:255',
            'account_number' => 'sometimes|string|max:50|unique:bank_accounts,account_number,' . $id,
            'account_type' => 'sometimes|in:current,savings,domiciliary',
            'currency' => 'sometimes|string|max:3',
            'is_primary' => 'sometimes|boolean',
            'is_active' => 'sometimes|boolean',
            'notes' => 'nullable|string',
        ]);

        $account->update($validated);

        return response()->json(['data' => $account->fresh()->load('company'), 'message' => 'Bank account updated successfully']);
    }

    public function destroy($id)
    {
        $user = $request->user();
        $account = BankAccount::where('company_id', $user->company_id)->findOrFail($id);

        // Prevent deletion if account has transactions
        $hasExpenses = $account->expenses()->count() > 0;
        $hasInvoices = $account->invoices()->count() > 0;

        if ($hasExpenses || $hasInvoices) {
            return response()->json(['message' => 'Cannot delete account with existing transactions. Deactivate instead.'], 400);
        }

        $account->delete();

        return response()->json(['message' => 'Bank account deleted successfully']);
    }

    // Get bank accounts for dropdown (simplified)
    public function list(Request $request)
    {
        $user = $request->user();
        // Base accounts: depending on user role
        if ($user->isSuperAdmin()) {
            $accounts = BankAccount::with('company')
                ->where('is_active', true)
                ->select('id', 'account_name', 'bank_name', 'account_number', 'currency', 'is_primary', 'current_balance', 'company_id')
                ->orderBy('company_id')
                ->orderBy('is_primary', 'desc')
                ->orderBy('account_name')
                ->get();
        } else {
            $accounts = BankAccount::where('company_id', $user->company_id)
                ->where('is_active', true)
                ->select('id', 'account_name', 'bank_name', 'account_number', 'currency', 'is_primary', 'current_balance')
                ->orderBy('is_primary', 'desc')
                ->orderBy('account_name')
                ->get();
        }

        // Optionally include super-admin holding accounts in the response
        if ($request->boolean('include_holdings')) {
            try {
                $holdingAccounts = \App\Models\SuperAdminBankAccount::where('is_active', true)
                    ->select('id', 'account_name', 'bank_name', 'account_number', 'currency', 'is_primary', 'current_balance')
                    ->orderBy('is_primary', 'desc')
                    ->orderBy('account_name')
                    ->get();

                // Tag holding accounts with a source so clients can distinguish if needed
                $holdingAccounts->transform(function ($a) {
                    $a->source = 'holding';
                    return $a;
                });

                // Merge company accounts and holdings
                $accounts = $accounts->values()->merge($holdingAccounts->values());
            } catch (\Exception $e) {
                // If fetching holdings fails, ignore and return base accounts
            }
        }

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

    // Transfer funds between bank accounts
    public function transfer(Request $request)
    {
        $user = $request->user();
        
        $validated = $request->validate([
            'from_account_id' => 'required|integer|exists:bank_accounts,id',
            'to_account_id' => 'required|integer|exists:bank_accounts,id|different:from_account_id',
            'amount' => 'required|numeric|min:0.01',
            'notes' => 'nullable|string|max:500',
        ]);

        $fromAccount = BankAccount::where('company_id', $user->company_id)
            ->where('id', $validated['from_account_id'])
            ->first();
        
        $toAccount = BankAccount::where('company_id', $user->company_id)
            ->where('id', $validated['to_account_id'])
            ->first();

        if (!$fromAccount || !$toAccount) {
            return response()->json(['message' => 'One or both accounts not found'], 404);
        }

        if ($fromAccount->current_balance < $validated['amount']) {
            return response()->json([
                'message' => 'Insufficient balance in source account',
                'required' => $validated['amount'],
                'available' => $fromAccount->current_balance,
                'shortfall' => $validated['amount'] - $fromAccount->current_balance
            ], 422);
        }

        if ($fromAccount->currency !== $toAccount->currency) {
            return response()->json(['message' => 'Cannot transfer between different currencies'], 422);
        }

        // Perform transfer
        DB::beginTransaction();
        try {
            $fromAccount->debit($validated['amount']);
            $toAccount->credit($validated['amount']);
            
            DB::commit();
            
            return response()->json([
                'data' => [
                    'from_account' => $fromAccount->fresh(),
                    'to_account' => $toAccount->fresh(),
                    'amount' => $validated['amount'],
                    'notes' => $validated['notes'] ?? null
                ],
                'message' => 'Transfer completed successfully'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['message' => 'Transfer failed: ' . $e->getMessage()], 500);
        }
    }
}
