<?php

namespace App\Http\Controllers;

use App\Models\Page;
use App\Models\Setting;
use Illuminate\Http\Request;

class PageReportController extends Controller
{
    public function show(Request $request, Page $page)
    {
        $page->load([
            'ledger.entity',
            'ledger.branch',
            'ledger.center',
            'ledger.project',
            'debitAccount.party',
            'creditAccount.party'
        ]);

        $dateFrom = $request->input('date_from');
        $dateTo = $request->input('date_to');

        if ($request->has('filter')) {
            $withOpeningBalance = $request->has('with_opening_balance');
            $withNotes = $request->has('with_notes');
            $hideTransactionNumber = $request->has('hide_transaction_number');
            $hideReference = $request->has('hide_reference');
            $hideCreditParty = $request->has('hide_credit_party');
        } else {
            $withOpeningBalance = true;
            $withNotes = false;
            $hideTransactionNumber = true;
            $hideReference = true;
            $hideCreditParty = false;
        }

        $query = $page->transactions()->where('is_active', true);

        if ($dateFrom) {
            $query->whereDate('transaction_date', '>=', $dateFrom);
        }
        if ($dateTo) {
            $query->whereDate('transaction_date', '<=', $dateTo);
        }
        if (!$withNotes) {
            $query->where('type', '!=', 'note');
        }

        // Calculate Opening Balance if requested and there is a dateFrom
        $openingBalance = 0;
        $openingDebit = 0;
        $openingCredit = 0;

        if ($withOpeningBalance && $dateFrom) {
            $prevTransactions = $page->transactions()
                ->where('is_active', true)
                ->where('type', '!=', 'note')
                ->whereDate('transaction_date', '<', $dateFrom)
                ->get();
            $openingDebit = $prevTransactions->sum('debit_amount');
            $openingCredit = $prevTransactions->sum('credit_amount');
            $openingBalance = $openingDebit - $openingCredit;
        }

        // Fetch transactions for the report period, ordered ascendingly for the report
        $transactions = $query->orderBy('transaction_date', 'asc')->orderBy('id', 'asc')->get();

        $settings = Setting::pluck('value', 'key')->toArray();

        // Calculate running balance for the report
        $runningBalance = $openingBalance;
        foreach ($transactions as $trx) {
            if ($trx->type !== 'note') {
                $runningBalance += $trx->debit_amount - $trx->credit_amount;
            }
            $trx->running_balance = $runningBalance;
        }

        $totalDebit = $transactions->sum('debit_amount') + ($withOpeningBalance ? $openingDebit : 0);
        $totalCredit = $transactions->sum('credit_amount') + ($withOpeningBalance ? $openingCredit : 0);
        $netBalance = $totalDebit - $totalCredit;

        $tafqeet = $this->getTafqeet($netBalance, $settings);
        
        $finalStatus = '';
        if ($netBalance > 0) {
            $finalStatus = "المتبقي على ({$page->debitAccount->party->name}) لصالح ({$page->creditAccount->party->name})";
        } elseif ($netBalance < 0) {
            $finalStatus = "المتبقي على ({$page->creditAccount->party->name}) لصالح ({$page->debitAccount->party->name})";
        } else {
            $finalStatus = "الحساب مطابق (صفر)";
        }

        // Process Footer Templates
        $timezone = $settings['timezone'] ?? 'Asia/Riyadh';
        $now = now($timezone);
        $user = auth()->user()->name ?? '';
        $date = $now->format($settings['date_format'] ?? 'Y-m-d');
        $time = $now->format(($settings['time_format'] ?? '12') === '12' ? 'h:i A' : 'H:i');
        $printTimestamp = $date . ' - ' . $time;

        $footerRight = str_replace(['{user}', '{date}', '{time}'], [$user, $date, $time], $settings['footer_print_right'] ?? '');
        $footerRight = str_replace('{page}', '<span class="page-number"></span>', $footerRight);

        $footerCenter = str_replace(['{user}', '{date}', '{time}'], [$user, $date, $time], $settings['footer_print_center'] ?? '');
        $footerCenter = str_replace('{page}', '<span class="page-number"></span>', $footerCenter);

        $footerLeft = str_replace(['{user}', '{date}', '{time}'], [$user, $date, $time], $settings['footer_print_left'] ?? '');
        $footerLeft = str_replace('{page}', '<span class="page-number"></span>', $footerLeft);

        return view('pages.report', compact(
            'page',
            'transactions',
            'settings',
            'dateFrom',
            'dateTo',
            'openingBalance',
            'openingDebit',
            'openingCredit',
            'withOpeningBalance',
            'hideTransactionNumber',
            'hideReference',
            'footerRight',
            'footerCenter',
            'footerLeft',
            'tafqeet',
            'finalStatus',
            'totalDebit',
            'totalCredit',
            'netBalance',
            'hideCreditParty',
            'printTimestamp'
        ));
    }

    private function getTafqeet($amount, $settings)
    {
        if (!$amount || !is_numeric($amount)) return '';

        $currencyCode = $settings['base_currency'] ?? 'SAR';
        $currency = \App\Models\Currency::where('code', $currencyCode)->first();
        
        $majorUnit = $currency->major_unit ?? 'ريال';
        $minorUnit = $currency->minor_unit ?? 'هللة';
        $lang = $settings['tafqeet_lang'] ?? 'ar';

        $amount = abs((float) $amount);
        $intPart = floor($amount);
        $decPart = (int) round(($amount - $intPart) * 100);

        $intSpell = \Illuminate\Support\Number::spell($intPart, locale: $lang);
        $result = "فقط " . $intSpell . " " . $majorUnit;

        if ($decPart > 0) {
            $decSpell = \Illuminate\Support\Number::spell($decPart, locale: $lang);
            $result .= " و " . $decSpell . " " . $minorUnit;
        }

        $result .= " لا غير";

        return $result;
    }
}
