<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\GeneralLedger;
use App\Models\MainSubAccount;
use App\Models\SubAccount1;
use App\Models\SubAccount2;
use App\Models\SubAccount3;
use App\Models\SubAccount4;
use App\Models\SubAccount5;
use App\Models\AccountTypes;
use App\Models\CompanySettings;
use PDF;

class ChartOfAccountsController extends Controller
{
    // Display initial form
    public function index()
    {
        $accountTypes = AccountTypes::orderBy('name')->get();
        $accounts = $this->buildChartOfAccounts();
        
        return view('reports.chart-of-accounts', compact('accountTypes', 'accounts'));
    }

    // Generate chart of accounts report
    public function generate(Request $request)
    {
        $request->validate([
            'account_type' => 'nullable|exists:account_types,id',
        ]);

        $accountTypeId = $request->account_type;
        $accountTypes = AccountTypes::orderBy('name')->get();
        
        $accounts = $this->buildChartOfAccounts($accountTypeId);

        return view('reports.chart-of-accounts', compact(
            'accountTypes',
            'accounts',
            'accountTypeId'
        ));
    }

    public function downloadPdf(Request $request)
    {
        $accountTypeId = $request->account_type;
        $accounts = $this->buildChartOfAccounts($accountTypeId);
        
        // Get company info
        $company = CompanySettings::first();

        $pdf = PDF::loadView('reports.chart-of-accounts-pdf', compact(
            'accounts',
            'company',
            'accountTypeId'
        ));

        return $pdf->download('chart-of-accounts-'.date('Y-m-d').'.pdf');
    }

    /**
     * Build hierarchical chart of accounts data - Only show leaf nodes (deepest levels)
     */
    private function buildChartOfAccounts($accountTypeId = null)
    {
        $accounts = [];

        // Get main accounts with optional filtering
        $mainAccountsQuery = GeneralLedger::with(['accountType', 'mainSubAccounts']);
        
        if ($accountTypeId) {
            $mainAccountsQuery->where('account_type', $accountTypeId);
        }

        $mainAccounts = $mainAccountsQuery->orderBy('code')->get();

        foreach ($mainAccounts as $mainAccount) {
            // Get main account's account type and financial category once
            $mainAccountType = $mainAccount->accountType->name ?? 'N/A';
            $mainFinancialCategory = $mainAccount->financial_category ?? 'N/A';
            
            // Process each main account branch to find leaf nodes
            $this->processAccountBranch($mainAccount, $accounts, $mainAccountType, $mainFinancialCategory);
        }

        // Sort accounts by full_code in natural order
        usort($accounts, function($a, $b) {
            return strnatcmp($a['full_code'], $b['full_code']);
        });

        return $accounts;
    }

    /**
     * Recursively process account branches to find leaf nodes
     */
    private function processAccountBranch($account, &$accounts, $mainAccountType, $mainFinancialCategory, $currentPath = [], $currentDescription = [])
    {
        $isMainAccount = $account instanceof GeneralLedger;

        if ($isMainAccount) {
            $code = $account->code;
            $description = $account->account_name;
        } else {
            $code = $account->account_code;
            $description = $account->sub_name;
        }

        // Add current level to path
        $newPath = array_merge($currentPath, [$code]);
        $newDescription = array_merge($currentDescription, [$description]);

        // Check if this account has children
        $hasChildren = false;

        if ($isMainAccount) {
            // Main account can have mainSubAccounts
            $hasChildren = $account->mainSubAccounts && $account->mainSubAccounts->count() > 0;
            $children = $hasChildren ? $account->mainSubAccounts : collect();
        } else {
            // Determine what type of sub-account this is and check for children
            $hasChildren = false;
            $children = collect();

            if ($account instanceof MainSubAccount) {
                $hasChildren = SubAccount1::where('parent_id', $account->id)->count() > 0;
                $children = $hasChildren ? SubAccount1::where('parent_id', $account->id)->get() : collect();
            } elseif ($account instanceof SubAccount1) {
                $hasChildren = SubAccount2::where('parent_id', $account->id)->count() > 0;
                $children = $hasChildren ? SubAccount2::where('parent_id', $account->id)->get() : collect();
            } elseif ($account instanceof SubAccount2) {
                $hasChildren = SubAccount3::where('parent_id', $account->id)->count() > 0;
                $children = $hasChildren ? SubAccount3::where('parent_id', $account->id)->get() : collect();
            } elseif ($account instanceof SubAccount3) {
                $hasChildren = SubAccount4::where('parent_id', $account->id)->count() > 0;
                $children = $hasChildren ? SubAccount4::where('parent_id', $account->id)->get() : collect();
            } elseif ($account instanceof SubAccount4) {
                $hasChildren = SubAccount5::where('parent_id', $account->id)->count() > 0;
                $children = $hasChildren ? SubAccount5::where('parent_id', $account->id)->get() : collect();
            }
            // SubAccount5 has no further children
        }

        if (!$hasChildren) {
            // This is a leaf node - add it to results
            // Always use the main account's account type and financial category
            $accounts[] = [
                'code' => end($newPath),
                'full_code' => implode(' > ', $newPath),
                'description' => implode(' / ', $newDescription),
                'account_type' => $mainAccountType,
                'financial_category' => $mainFinancialCategory,
                'level' => count($newPath) - 1
            ];
        } else {
            // This account has children - process each child
            // Pass down the main account's account type and financial category
            foreach ($children as $child) {
                $this->processAccountBranch($child, $accounts, $mainAccountType, $mainFinancialCategory, $newPath, $newDescription);
            }
        }
    }
}