<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Collection;
use App\Account;
use App\Payment;
use App\Returns;
use App\ReturnPurchase;
use App\Expense;
use App\Payroll;
use App\MoneyTransfer;
use DB;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Auth;
use App\FinancialTransaction;
use App\Services\MainCashAccount;
use Exception;


class AccountsController extends Controller
{
    public function index(Request $request)
    {
        $role = Role::find(Auth::user()->role_id);
        if($role->hasPermissionTo('account-index')){
            $transactionCategories = [
                'owner_deposit',
                'customer_payment',
                'curtain_order_payment',
                'purchase_payment',
                'purchase_return',
                'expense',
                'customer_refund',
                'tailor_payment',
                'reversal',
            ];

            $this->validate($request, [
                'period' => ['nullable', Rule::in(['all', 'day', 'week', 'month', 'year', 'custom'])],
                'start_date' => ['nullable', 'date', 'required_if:period,custom'],
                'end_date' => ['nullable', 'date', 'after_or_equal:start_date', 'required_if:period,custom'],
                'category' => ['nullable', Rule::in($transactionCategories)],
                'direction' => ['nullable', Rule::in(['in', 'out'])],
                'reference' => ['nullable', 'string', 'max:191'],
            ]);

            $lims_account_all = Account::where('account_no', 'MAIN-CASH')->where('is_active', true)->get();
            $selectedPeriod = $request->input('period', 'month');
            $transactionQuery = FinancialTransaction::query();
            $dateFormat = config('date_format') ?: 'd-m-Y';
            $filterLabel = trans('file.This Month') . ' - ' . now()->translatedFormat('F Y');

            if ($selectedPeriod === 'day') {
                $startDate = now()->copy()->startOfDay();
                $endDate = now()->copy()->endOfDay();
                $filterLabel = trans('file.Today') . ' - ' . now()->format($dateFormat);
                $transactionQuery->whereBetween('transaction_date', [$startDate, $endDate]);
            } elseif ($selectedPeriod === 'week') {
                $startDate = now()->copy()->startOfWeek();
                $endDate = now()->copy()->endOfWeek();
                $filterLabel = $startDate->format($dateFormat) . ' - ' . $endDate->format($dateFormat);
                $transactionQuery->whereBetween('transaction_date', [$startDate, $endDate]);
            } elseif ($selectedPeriod === 'year') {
                $startDate = now()->copy()->startOfYear();
                $endDate = now()->copy()->endOfYear();
                $filterLabel = trans('file.This Year') . ' - ' . now()->format('Y');
                $transactionQuery->whereBetween('transaction_date', [$startDate, $endDate]);
            } elseif ($selectedPeriod === 'custom') {
                $filterLabel = $request->start_date . ' - ' . $request->end_date;
                $transactionQuery
                    ->whereDate('transaction_date', '>=', $request->start_date)
                    ->whereDate('transaction_date', '<=', $request->end_date);
            } elseif ($selectedPeriod === 'all') {
                $filterLabel = trans('file.All Time');
            } else {
                $selectedPeriod = 'month';
                $startDate = now()->copy()->startOfMonth();
                $endDate = now()->copy()->endOfMonth();
                $transactionQuery->whereBetween('transaction_date', [$startDate, $endDate]);
            }

            if ($request->filled('category')) {
                $transactionQuery->where('category', $request->category);
            }
            if ($request->filled('direction')) {
                $transactionQuery->where('direction', $request->direction);
            }
            if ($request->filled('reference')) {
                $transactionQuery->where('reference_no', 'like', '%' . trim($request->reference) . '%');
            }

            $filteredCashIn = (float) (clone $transactionQuery)->where('direction', 'in')->sum('amount');
            $filteredCashOut = (float) (clone $transactionQuery)->where('direction', 'out')->sum('amount');
            $netChange = $filteredCashIn - $filteredCashOut;
            $recent_transactions = (clone $transactionQuery)
                ->latest('id')
                ->paginate(50)
                ->appends($request->query());

            return view('backend.account.index', compact(
                'lims_account_all',
                'recent_transactions',
                'transactionCategories',
                'selectedPeriod',
                'filterLabel',
                'filteredCashIn',
                'filteredCashOut',
                'netChange'
            ));
        }
        else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        return redirect('accounts')->with('not_permitted', trans('file.Only one cash account is allowed'));
    }

    public function ownerDeposit(Request $request)
    {
        $this->validate($request, [
            'amount' => ['required', 'numeric', 'min:0.01'],
            'note' => ['nullable', 'string', 'max:2000'],
            'transaction_date' => ['nullable', 'date'],
        ]);

        try {
            app(MainCashAccount::class)->deposit(
                (float) $request->amount,
                'owner_deposit',
                Account::class,
                app(MainCashAccount::class)->account()->id,
                'OWNER-' . date('YmdHis'),
                $request->note,
                $request->transaction_date ?: now()
            );
        } catch (Exception $e) {
            return redirect()->back()->with('not_permitted', $e->getMessage());
        }

        return redirect('accounts')->with('message', trans('file.Owner deposit recorded successfully'));
    }

    public function makeDefault($id)
    {
        return trans('file.Main cash account is always the default account');
    }

    public function edit($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        return redirect('accounts')->with('not_permitted', trans('file.Main cash account cannot be edited'));
    }

    public function balanceSheet()
    {
        $role = Role::find(Auth::user()->role_id);
        if($role->hasPermissionTo('balance-sheet')){
            $lims_account_list = Account::where('account_no', 'MAIN-CASH')->where('is_active', true)->get();
            $credit = [(float) FinancialTransaction::where('direction', 'in')->sum('amount')];
            $debit = [(float) FinancialTransaction::where('direction', 'out')->sum('amount')];
            return view('backend.account.balance_sheet', compact('lims_account_list', 'debit', 'credit'));
        }
        else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    public function accountStatement(Request $request)
    {
        $this->validate($request, [
            'start_date' => ['required', 'date'],
            'end_date' => ['required', 'date', 'after_or_equal:start_date'],
        ]);
        $lims_account_data = app(MainCashAccount::class)->account();
        $all_transaction_list = FinancialTransaction::whereDate('transaction_date', '>=', $request->start_date)
            ->whereDate('transaction_date', '<=', $request->end_date)
            ->orderBy('transaction_date')
            ->orderBy('id')
            ->get();
        $balance = $all_transaction_list->first()
            ? ($all_transaction_list->first()->balance_after
                + ($all_transaction_list->first()->direction === 'out'
                    ? $all_transaction_list->first()->amount
                    : -$all_transaction_list->first()->amount))
            : (float) $lims_account_data->total_balance;
        return view('backend.account.account_statement', compact('lims_account_data', 'all_transaction_list', 'balance'));
    }

    public function destroy($id)
    {
        return redirect('accounts')->with('not_permitted', trans('file.Main cash account cannot be deleted'));
    }
}
