• File: CreditSolicitationController.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/CreditSolicitationController.php
  • Date Modified: 12/18/2025 10:13 PM
  • File size: 84.97 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\AgregadoFamiliar;
use App\BeginSolicitation;
use App\BemGarantia;
use App\BusinessCreditRequest;
use App\BusinessCreditRequestNew25;
use App\BusinessRequestWarrentyFile;
use App\Classes\Auth;
use App\Classes\ImageUploader;
use App\Classes\SendResponse;
use App\Classes\TransactionGeneration;
use App\DadosNegocio;
use App\DadosSolicitante;
use App\DespesaMensal;
use App\Exports\CreditSolicitation;
use App\Imali\BusinessAccount;
use App\MaritalStatus;
use App\User;
// use Barryvdh\DomPDF\PDF;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class CreditSolicitationController extends Controller
{
    // Create Marital Status
    public function maritalStatus(Request $request)
    {

        $this->validate(
            $request,
            [
                'name' => 'required'
            ],
            [
                'name.required' => 'Campo name é obrigatório'
            ]
        );

        $marital_status = MaritalStatus::create([
            'name' => $request->name
        ]);

        if ($marital_status) return response()->json(['message' => 'Estado Civil salvo com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo do Estado Civil', 500]);
    }

    // Create Bem Garantia
    public function bemGarantia(Request $request)
    {

        $this->validate(
            $request,
            [
                'name' => 'required'
            ],
            [
                'name.required' => 'Campo name é obrigatório'
            ]
        );

        $bem_garantia = BemGarantia::create([
            'name' => $request->name
        ]);

        if ($bem_garantia) return response()->json(['message' => 'Bem de Garantia salvo com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo do Bem de Garantia', 500]);
    }

    // Create Agregado Familiar
    public function agregadoFamiliar(Request $request)
    {

        $this->validate(
            $request,
            [
                'household' => 'required',
                'family_dependents' => 'required|numeric'
            ],
            [
                'household.required' => 'Campo household é obrigatório',
                'family_dependents.required' => 'Campo family_dependents é obrigatório',
                'family_dependents.numeric' => 'Campo family_dependents é númerico',
            ]
        );

        $bem_garantia = AgregadoFamiliar::create([
            'household' => $request->household,
            'family_dependents' => $request->family_dependents,
            'own_house' => $request->own_house,
            'rented_house' => $request->rented_house
        ]);

        if ($bem_garantia) return response()->json(['message' => 'Dados do agregado Familiar salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Despesa Mensal
    public function despesaMensal(Request $request)
    {

        $this->validate(
            $request,
            [
                'food' => 'required|numeric',
                'salary' => 'required|numeric',
                'expenses' => 'required|numeric',
                'employee' => 'required|numeric',
                'transport' => 'required|numeric',
                'education' => 'required|numeric',
                'clothes' => 'required|numeric',
                'health' => 'required|numeric',
                'leisure' => 'required|numeric',

            ],
            [
                'food.required' => 'Campo food é obrigatório',
                'salary.required' => 'Campo salary é obrigatório',
                'expenses.required' => 'Campo expenses é obrigatório',
                'employee.required' => 'Campo employee é obrigatório',
                'transport.required' => 'Campo transport é obrigatório',
                'education.required' => 'Campo education é obrigatório',
                'clothes.required' => 'Campo clothes é obrigatório',
                'health.required' => 'Campo health é obrigatório',
                'leisure.required' => 'Campo leisure é obrigatório',

                'food.numeric' => 'Campo food é númerico',
                'salary.numeric' => 'Campo salary é númerico',
                'expenses.numeric' => 'Campo expenses é númerico',
                'employee.numeric' => 'Campo employee é númerico',
                'transport.numeric' => 'Campo transport é númerico',
                'education.numeric' => 'Campo education é númerico',
                'clothes.numeric' => 'Campo clothes é númerico',
                'health.numeric' => 'Campo health é númerico',
                'leisure.numeric' => 'Campo leisure é númerico',
            ]
        );

        $despesa = DespesaMensal::create([
            'food' => $request->food,
            'salary' => $request->salary,
            'expenses' => $request->expenses,
            'employee' => $request->employee,
            'transport' => $request->transport,
            'education' => $request->education,
            'clothes' => $request->clothes,
            'health' => $request->health,
            'leisure' => $request->leisure,
            'other' => $request->other,
            'other_description' => $request->other_description,
            'total' => $request->total
        ]);

        if ($despesa) return response()->json(['message' => 'Dados de Despesa Mensal salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create beginSolicitation
    public function beginSolicitation(Request $request)
    {

        $this->validate(
            $request,
            [
                'credit_amount' => 'required|numeric|min:1',
                'duration' => 'required|numeric|min:1',
            ],
            [
                'credit_amount.required' => 'Campo credit_amount é obrigatório',
                'credit_amount.numeric' => 'Campo credit_amount deve ser um número',
                'credit_amount.min' => 'Campo credit_amount deve ser maior que 1',
                'duration.required' => 'Campo duration é obrigatório',
                'duration.numeric' => 'Campo duration deve ser um número',
                'duration.min' => 'Campo duration deve ser maior que 0',
            ]
        );

        $begin_solicitation = BeginSolicitation::create([
            'credit_amount' => $request->credit_amount,
            'duration' => $request->duration,
            'business_account_id'  => $request->business_account_id,
            'preparation_fee'  => $request->preparation_fee,
            'comission'  => $request->comission,
            'fee'  => $request->fee,
            'total_cost_credit'  => $request->total_cost_credit,
            'total_consumer_value'  => $request->total_consumer_value
        ]);

        if ($begin_solicitation) return response()->json(['message' => 'Dados de BeginSolicitation salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Dados do Negocio
    public function dadosNegocio(Request $request)
    {

        $this->validate(
            $request,
            [
                'business_address' => 'required',
                'business_accounts_id' => 'required|numeric',
                'activity_type' => 'required|numeric',
                'antiquity' => 'required',
                'current_location_antiquity' => 'required',
                'monthly_income' => 'required'
            ],
            [
                'business_address.required' => 'Campo business_address é obrigatório',
                'business_accounts_id.required' => 'Campo business_accounts_id é obrigatório',
                'business_accounts_id.numeric' => 'Campo business_accounts_id é numeric',
                'activity_type.required' => 'Campo activity_type é obrigatório',
                'activity_type.numeric' => 'Campo activity_type é numeric',
                'antiquity.required' => 'Campo antiquity é obrigatório',
                'current_location_antiquity.required' => 'Campo current_location_antiquity é obrigatório',
                'monthly_income.required' => 'Campo monthly_income é obrigatório',
            ]
        );

        $dados_negocio = DadosNegocio::create([
            'business_address' => $request->business_address,
            'business_accounts_id' => $request->business_accounts_id,
            'activity_type' => $request->activity_type,
            'antiquity' => $request->antiquity,
            'current_location_antiquity' => $request->current_location_antiquity,
            'other_activities' => $request->other_activities,
            'monthly_income' => $request->monthly_income
        ]);

        if ($dados_negocio) return response()->json(['message' => 'Dados do Negocio salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Dados do Solicitante
    public function dadosSolicitante(Request $request)
    {
        $error = $this->solicitante_params($request);

        if ($error && $error->getStatusCode() != 200) return $error;

        $dados_negocio = DadosSolicitante::create([
            'name' => $request->name,
            'business_accounts_id' => $request->business_accounts_id,
            'father_name' => $request->father_name,
            'mother_name' => $request->mother_name,
            'marital_status' => $request->marital_status,
            'marital_name' => $request->marital_name,
            'phone' => $request->phone,
            'alternative_phone' => $request->alternative_phone,
            'nuit' => $request->nuit,
            'identity_number' => $request->identity_number,
            'province_id' => $request->province_id,
            'quarter' => $request->quarter,
            'address' => $request->address,
            'agregado_familiars_id' => $request->agregado_familiars_id,
            'despesa_mensals_id' => $request->despesa_mensals_id
        ]);

        if ($dados_negocio) {
            try {
                //code...
                $dados_negocio->bensGarantia()->syncWithPivotValues(
                    $request->bem_garantias_id,
                    ['dados_solicitantes_id' => $dados_negocio->id]
                );
                $dados_negocio->save();

                return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso'], 200);
            } catch (\Throwable $th) {
                //throw $th;
                return response()->json(['message' => 'Houve uma falha no registo dos dados', 'exception' => $th], 500);
            }
        }
    }

    private function solicitante_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'name' => 'required',
                    'business_accounts_id' => 'required',
                    'father_name' => 'required',
                    'mother_name' => 'required',
                    'marital_status' => 'required',
                    // 'marital_name' => 'required',
                    'phone' => 'required|numeric',
                    'nuit' => 'required|min:9|max:9',
                    'identity_number' => 'required',
                    'province_id' => 'required',
                    // 'quarter' => 'required',
                    'address' => 'required',
                    'agregado_familiars_id' => 'required',
                    'despesa_mensals_id' => 'required',
                    // 'bem_garantias_id' => 'required',

                ],
                [
                    'name.required' => 'Campo name é obrigatório',
                    'business_accounts_id.required' => 'Campo business_accounts_id é obrigatório',
                    'father_name.required' => 'Campo father_name é obrigatório',
                    'mother_name.required' => 'Campo mother_name é obrigatório',
                    'marital_status.required' => 'Campo marital_status é obrigatório',
                    // 'marital_name.required' => 'Campo marital_name é obrigatório',
                    'phone.required' => 'Campo phone é obrigatório',
                    'phone.numeric' => 'Campo phone é numérico',
                    'nuit.required' => 'Campo nuit é obrigatório',
                    'nuit.min' => 'Campo nuit deve ter 9 carateres',
                    'nuit.max' => 'Campo nuit deve ter 9 carateres',
                    'identity_number.required' => 'Campo identity_number é obrigatório',
                    'province_id.required' => 'Campo province_id é obrigatório',
                    // 'quarter.required' => 'Campo quarter é obrigatório',
                    'address.required' => 'Campo address é obrigatório',
                    'agregado_familiars_id.required' => 'Campo agregado_familiars_id é obrigatório',
                    'despesa_mensals_id.required' => 'Campo despesa_mensals_id é obrigatório',
                    // 'bem_garantias_id.required' => 'Selecione um ou varios bens de garantia',

                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }


    private function dados_negocio_validator($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'antiquity' => 'required',
                    'current_location_antiquity' => 'required',
                    'monthly_income' => 'required'
                ],
                [
                    'antiquity.required' => 'Campo antiquity é obrigatório',
                    'current_location_antiquity.required' => 'Campo current_location_antiquity é obrigatório',
                    'monthly_income.required' => 'Campo monthly_income é obrigatório',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }

    private function begin_solicitation_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'credit_amount' => 'required|numeric|min:1',
                    'duration' => 'required|numeric|min:1',
                    'preparation_fee' => 'required',
                ],
                [
                    'credit_amount.required' => 'Campo credit_amount é obrigatório',
                    'credit_amount.numeric' => 'Campo credit_amount deve ser um número',
                    'credit_amount.min' => 'Campo credit_amount deve ser maior que 0',
                    'duration.required' => 'Campo duration é obrigatório',
                    'duration.numeric' => 'Campo duration deve ser um número',
                    'duration.min' => 'Campo duration deve ser maior que 0',
                    'preparation_fee.required' => 'Campo preparation_fee é obrigatório',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }

    private function business_credit_request_solicitation_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'document_type' => 'required|in:MPESA,EMOLA,BANK,DECLARATION,WATER,LIGHT',
                    'document_file' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                    'declaration_market' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                    'photo_market' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                ],
                [
                    'document_type.required' => 'Campo document_type é obrigatório',
                    'document_type.in' => 'document_type só permite os seguintes tipos:MPESA,EMOLA,BANK,DECLARATION,WATER,LIGHT',

                    'document_file.required' => 'Campo document_file é obrigatório',
                    'document_file.file' => 'O campo document_file é um ficheiro',
                    'document_file.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'document_file.max' => 'Tamanho máximo permitido para document_file é 4MB',

                    'declaration_market.required' => 'Campo declaration_market é obrigatório',
                    'declaration_market.file' => 'O campo declaration_market é um ficheiro',
                    'declaration_market.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'declaration_market.max' => 'Tamanho máximo permitido para declaration_market é 4MB',

                    'photo_market.required' => 'Campo photo_market é obrigatório',
                    'photo_market.file' => 'O campo photo_market é um ficheiro',
                    'photo_market.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'photo_market.max' => 'Tamanho máximo permitido para photo_market é 4MB',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }


    // METODO FINAL ::.

    // Create AgregadoFamiliar
    private function agregado_familiar($request, $userPayer)
    {
        return AgregadoFamiliar::create([
            'household' => $request->household,
            'family_dependents' => $request->family_dependents,
            // 'own_house' => $request->own_house,
            'residency_type' => $request->residency_type,
            'business_accounts_id' => $userPayer->account_id
        ]);
    }

    // Create Despesa Mensal
    private function despesa_mensal($request, $userPayer)
    {
        $total = collect([
            $request->food,
            $request->rent,
            $request->expenses,
            $request->employee,
            $request->transport,
            $request->education,
            $request->clothes,
            $request->health,
            $request->leisure,
            // $request->other
        ])->filter()->sum();

        return DespesaMensal::create([
            'food' => $request->food,
            'rent' => $request->rent,
            'expenses' => $request->expenses,
            'employee' => $request->employee,
            'transport' => $request->transport,
            'education' => $request->education,
            'clothes' => $request->clothes,
            'health' => $request->health,
            'leisure' => $request->leisure,
            'other' => $request->other,
            'other_description' => $request->other_description,
            'total' => $total, // Soma automática
            'business_accounts_id' => $userPayer->account_id
        ]);
    }

    // Create Dados do Negocio
    private function dados_negocio($request, $userPayer)
    {

        return DadosNegocio::create([
            // 'business_address' => $request->business_address,
            'business_address' => $userPayer->company_address,
            'business_accounts_id' => $userPayer->account_id,
            // 'activity_type' => $request->activity_type,
            'activity_type' => $userPayer->activity_branch,
            'antiquity' => $request->antiquity,
            'current_location_antiquity' => $request->current_location_antiquity,
            'other_activities' => $request->other_activities,
            'monthly_income' => $request->monthly_income
        ]);
    }

    // Create beginSolicitation
    private function dados_begin_solicitation($request, $userPayer, $provider)
    {
        return BeginSolicitation::create([
            'credit_amount' => $request->credit_amount,
            'duration' => $request->duration,
            'business_account_id'  => $userPayer->account_id,

            'request_account'  => $userPayer->account_number, // todo NEW 07-11-2025
            'provider_account'  => $provider->account_number, // todo NEW 07-11-2025
            'provider_id'  => $provider->id, // todo NEW 07-11-2025

            'preparation_fee'  => $request->preparation_fee,
            'comission'  => $request->comission,
            'fee'  => $request->fee,
            'total_cost_credit'  => $request->total_cost_credit,
            'total_consumer_value'  => $request->total_consumer_value,

            'remaing_amount' => $request->total_cost_credit,
        ]);

        // $table->string('request_account')->nullable();
        // $table->string('provider_account')->nullable();
        // $table->integer('provider_id')->nullable();
    }

    // Create Dados do solicitante
    private function dados_solicitante($request, $userPayer, $agregado_familiar, $despesa)
    {
        $dados_solicitante = DadosSolicitante::create([
            // 'name' => $request->name,
            'name' => $userPayer->name . ' ' . $userPayer->last_name,
            'business_accounts_id' => $userPayer->account_id,
            // 'father_name' => $request->father_name,
            'father_name' => $request->father_name,
            'mother_name' => $request->mother_name,
            'marital_status' => $request->marital_status,
            'marital_name' => $request->marital_name,
            // 'phone' => $request->phone,
            'phone' => $userPayer->owner_phone,
            'alternative_phone' => $request->alternative_phone,
            // 'nuit' => $request->nuit,
            // 'nuit' => $userPayer->company_nuit,
            // 'nuit' => $userPayer->business_type === 'INFORMAL' ? $request->nuit : $userPayer->company_nuit, // todo NEW 14.10.2025
            'nuit' => !empty($userPayer->company_nuit) ? $userPayer->company_nuit : $request->nuit,
            'identity_number' => $request->identity_number,
            // 'province_id' => $request->province_id,
            'province_id' => $userPayer->country_id,
            'quarter' => $request->quarter,
            'address' => $request->address,
            'agregado_familiars_id' => $agregado_familiar->id, //! REMOVER
            'despesa_mensals_id' => $despesa->id
        ]);

        // 🔄 Actualizar company_nuit na tabela business_accounts (se estiver vazio)
        if (empty($userPayer->company_nuit) && !empty($dados_solicitante->nuit)) {
            // Garante que estás a atualizar a tabela correta
            $businessAccount = BusinessAccount::find($userPayer->account_id);

            if ($businessAccount) {
                $businessAccount->update([
                    'company_nuit' => $dados_solicitante->nuit,
                ]);
            }
        }

        return $dados_solicitante;
    }

    // Business Credit Solicitation
    private function business_credit_request($request, $userPayer, $dados_negocio, $dados_begin_solicitation)
    {
        // Registar a transacao de transferencia | Envio de Dinheiro
        $random = new TransactionGeneration();
        $transactionReference = $random->generateTransaction();

        $credit_request = BusinessCreditRequest::create([
            'transaction_id' => $transactionReference,
            'credit_reference' => $request->credit_reference,

            'business_accounts_id' => $userPayer->account_id,

            'document_type' => $request->document_type,
            'document_file' => $request->document_file,

            'declaration_market' => $request->declaration_market,
            'photo_market' => $request->photo_market,

            'dados_negocios_id' => $dados_negocio->id,
            'dados_begin_solicitation' => $dados_begin_solicitation->id,
            'step' => 1,
        ]);

        return $credit_request->fresh();
    }

    // Images::.
    private function businessRequestWarrenty($request, $userPayer, $credit_request)
    {
        $new_items = [];
        $img_uploader = new ImageUploader();

        foreach ($request->itens as $index => $item) {

            if (!$request->hasFile('itens.' . $index . '.img')) {

                $item['img'] = $img_uploader->generateImageUrlName25(new Request(['img' => $item['img']]), 'img', 'documentos/', 11);
            } else {
                $item['img'] = $img_uploader->generateImageUrlName25($request, 'itens.' . $index . '.img', 'documentos/', 11);

                // $updateData[$field] = $img_uploader->generateImageUrlName25($request, $field, 'documentos/', 11);
            }

            $item['business_accounts_id'] = $userPayer->account_id;
            $item['created_at'] = $credit_request->created_at;
            $item['updated_at'] = $credit_request->updated_at;
            unset($item['img_type']);

            array_push($new_items, $item);
        }

        if ($credit_request) {
            try {
                //code...
                $credit_request->items()->sync($new_items);

                return response()->json(['message' => 'Dados registados com sucesso!'], 200);
            } catch (\Throwable $th) {
                //throw $th;
                return response()->json(['message' => 'Erro ao salvar', 'exception' => $th], 500);
            }
        } else {
            return response()->json(['message' => 'Nao pode registar os dados informados ja estao em uso'], 400);
        }
    }


    // METODO DA VERDADE..
    public function business_credit_request_method(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        // todo NEW 07-11-2025
        // $provider = User::getAccount($request->provider_account);
        // if (!$provider) return SendResponse::errorResp404notfound('Conta do provedor não encontrada', 'Provider Account Not Found');

        // if (!$provider->accept_loans) return SendResponse::errorResp404notfound('Esta conta do provedor não aceita emprestimos', 'This Provider Account does not accept loans');

        // return $provider;

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->whereNotNull('transaction_id')
            ->where('transaction_id', '!=', '')
            ->whereNotIn('status', ['PENDING', 'UNDER_EVALUATION', 'APPROVED', 'REJECTED'])
            ->first();

        if (!$business_request || !in_array($business_request->step, [1, 2, 3])) {
            // Criar Solicitação
            return $this->businessCreditRequest($request, $userPayer);
        }

        switch ($business_request->step) {
            case 1:
                // Chamar método de step 2;
                return $this->businessCreditRequest2($request, $userPayer);
                break;
            case 2:
                // Chamar método de step 3";
                return $this->businessCreditRequest3($request, $userPayer);
                break;
            case 3:
                Log::info('ENTROU NO STEP 3 - FINALIZAR SOLICITAÇÃO',['request_data' => $request->all()]);
                // Dados de Registo Finalizados...";
                // return $this->businessCreditRequest($request, $userPayer);

                // Se o step 3 já foi atingido, apenas verificar se é pré-visualização ou continuação
                // if ($request->has('continue') && $request->continue == true) {
                    // Já está no passo 3, usuário quer continuar → apenas atualizar status
                    

                    $business_request->update(['status' => 'PENDING']);

                    (new CreditSolicitation($request->transaction_id))->exportPDF();

                    return response()->json([
                        'message' => 'Solicitação submetida com sucesso!',
                        'step' => 3,
                        'transaction_id' => $business_request->transaction_id
                    ], 200);

                    break;
                // }

            default:
                // Criar novamente
                return $this->businessCreditRequest($request, $userPayer);
                break;
        }
    }
    // METODO DA VERDADE..

    // todo --- STEP 1
    // Create Dados do Solicitante 
    public function businessCreditRequest(Request $request, $userPayer)
    {

        // todo NEW 07-11-2025
        $provider = User::getAccount($request->provider_account);
        if (!$provider) return SendResponse::errorResp404notfound('Conta do provedor não encontrada', 'Provider Account Not Found');

        if (!$provider->accept_loans) return SendResponse::errorResp404notfound('Esta conta do provedor não aceita emprestimos', 'This Provider Account does not accept loans');

        // return $provider;
        try {
            DB::beginTransaction();

            $error = $this->dados_negocio_validator($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $dados_negocio = $this->dados_negocio($request, $userPayer); // STEP 1

            $error = $this->begin_solicitation_params($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $dados_begin_solicitation = $this->dados_begin_solicitation($request, $userPayer, $provider); // STEP 1

            $error = $this->business_credit_request_solicitation_params($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $credit_request = $this->business_credit_request($request, $userPayer, $dados_negocio, $dados_begin_solicitation); // STEP 1

            $this->uploadImages($request, $credit_request);

            DB::commit();

            if ($credit_request) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso', 'data' => $credit_request]);
        } catch (\Throwable $th) {
            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }


    private function validate_transaction_id($request)
    {
        return $this->validate(
            $request,
            [
                'transaction_id' => 'required'
            ],
            [
                'transaction_id.required' => 'Campo transaction_id é obrigatório. Informe o valor do parametro transaction_id'
            ]
        );
    }

    // todo --- STEP 2
    public function businessCreditRequest2(Request $request, $userPayer)
    {
        // return $userPayer;

        $this->validate_transaction_id($request);

        // 👇🏽 Aqui entra a verificação do NUIT

        // if ($userPayer->business_type === 'INFORMAL' && empty($request->nuit)) {
        //     return response()->json([
        //         'info' => false,
        //         'message' => 'O campo NUIT é obrigatório para contas Business informais.'
        //     ], 422);
        // }

        if (!$userPayer->company_nuit && empty($request->nuit)) {
            return response()->json([
                'info' => false,
                'message' => 'O campo NUIT é obrigatório para contas Business informais.'
            ], 422);
        }

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->where('step', 1)
            ->where('status', 'IN_CREATION')
            ->first();


        if (!$business_request) return SendResponse::errorResp404notfound('Solicitação não encontrada', 'Solicitation Not Found');

        // return $business_request;

        try {
            DB::beginTransaction();

            $despesa = $this->despesa_mensal($request, $userPayer); // STEP 2
            $agregado_familiar = $this->agregado_familiar($request, $userPayer); // STEP 2
            $dados_solicitante = $this->dados_solicitante($request, $userPayer, $agregado_familiar, $despesa); // STEP 2

            $business_request->update([
                'step' => 2,
                'dados_solicitantes_id' => $dados_solicitante->id
            ]);

            DB::commit();

            if ($dados_solicitante) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso']);
        } catch (\Throwable $th) {

            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }

    // todo --- STEP 3
    public function businessCreditRequest3(Request $request, $userPayer)
    {
        $this->validate_transaction_id($request); // STEP 3

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->where('step', 2)
            ->where('status', 'IN_CREATION')
            ->first();

        if (!$business_request) return SendResponse::errorResp404notfound('Solicitação não encontrada', 'Solicitation Not Found');

        try {
            DB::beginTransaction();

            $this->business_credit_params($request);

            $this->businessRequestWarrenty($request, $userPayer, $business_request);
            // $business_warrenty_files = $this->businessRequestWarrenty($request, $userPayer, $business_request);

            $business_request->update([
                'step' => 3,
                'status' => 'IN_CREATION'
            ]);

     

            // dados
            $begin_solicitation_data = BeginSolicitation::find($business_request->dados_begin_solicitation);
            // Buscar dados relacionados
            $dados_negocio = DadosNegocio::find($business_request->dados_negocios_id);
            // Buscar dados relacionados
            $dados_solicitante = DadosSolicitante::find($business_request->dados_solicitantes_id);
            // return $dados_solicitante;
            $agregado_familiar = AgregadoFamiliar::find($dados_solicitante->agregado_familiars_id);
            // return $agregado_familiar;
            $despesas_mensais = DespesaMensal::find($dados_solicitante->despesa_mensals_id);
            // return $agregado_familiar;
            $itens = BusinessRequestWarrentyFile::query()->where('request_id', $business_request->id)->get();
            // dados
            
            Log::info('STEP 3 - FINALIZAR SOLICITAÇÃO',['request_data' => $request->all()]);
            // return $business_request;
            $dados_completos = [
                'message' => 'Dados da Solicitação em criação',
                'solicitacao_credito' => $business_request,
                'begin_solicitation_data' => $begin_solicitation_data,
                'dados_negocio' => $dados_negocio,
                'dados_solicitante' => $dados_solicitante,
                'agregado_familiar' => $agregado_familiar,
                'despesas_mensais' => $despesas_mensais,
                'itens' => $itens,
            ];

            // 🔸 Se o utilizador ainda não clicou em CONTINUAR → apenas mostra a pré-visualização -  esse codigo na existe
           // if (!$request->has('continue') || $request->continue == false) {
            //        Log::info('Não clicou em continuar.');

           //     return response()->json($dados_completos, 200);
            //}
        
            
            Log::info('Solicitação de Crédito',['request_data' => $request->all()]);
            // 🔸 Se o utilizador clicou em CONTINUAR → muda status e gera PDF
            $business_request->update([
                'status' => 'PENDING',
            ]);
            
            (new CreditSolicitation($request->transaction_id))->exportPDF();
            DB::commit();
            return response()->json([
                'message' => 'Solicitação submetida com sucesso!',
                'dados' => $dados_completos
            ], 200);

            // if ($business_warrenty_files) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso']);
        } catch (\Throwable $th) {

            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }

    private function uploadImages($request, $credit_request)
    {
        $img_uploader = new ImageUploader();
        $updateData = [];

        // Lista de campos a serem processados
        $fields = [
            'document_file',
            'declaration_market',
            'photo_market',
            // 'img',
        ];

        foreach ($fields as $field) {
            if ($request->hasFile($field) && !$this->isPdf($request->$field)) {
                $updateData[$field] = $img_uploader->generateImageUrlName25($request, $field, 'documentos/', 11);
            }
        }

        // Apenas atualiza se houver novos dados
        if (!empty($updateData)) {
            $credit_request->update($updateData);
        }

        // 
        // if (!empty($updateData)) {
        //     $business_warrenty_files->update($updateData);
        // }
    }

    private function isPdf($file)
    {
        return strtolower($file->getClientOriginalExtension()) === 'pdf';
    }

    // Imagens
    private function business_credit_params($request)
    {
        $this->validate(
            $request,
            [
                // Os campos abaixo agora são opcionais e não obrigatórios
                'document_file' => 'nullable',
                'itens' => 'required|array',
                'itens.*.item' => 'required|string',
                'itens.*.img_type' => 'required|string|in:base64,file',
                'itens.*.img' => [
                    'required',
                    function ($attribute, $value, $fail) use ($request) {
                        // Extrai o índice do item
                        preg_match('/itens\.(\d+)\.img/', $attribute, $matches);
                        $index = $matches[1] ?? null;
                        $img_type = data_get($request, "itens.$index.img_type");

                        if ($img_type === 'file') {
                            if (!$value instanceof \Illuminate\Http\UploadedFile) {
                                $fail("O campo $attribute deve ser um arquivo.");
                                return;
                            }
                            $ext = strtolower($value->getClientOriginalExtension());
                            if (!in_array($ext, ['jpg', 'jpeg', 'png'])) {
                                $fail("O campo $attribute deve ser um arquivo do tipo: jpg, jpeg, png.");
                            }
                        } elseif ($img_type === 'base64') {
                            if (!is_string($value) || !preg_match('/^data:image\/(png|jpeg|jpg);base64,/', $value)) {
                                $fail("O campo $attribute deve ser uma imagem base64 válida.");
                            }
                        } else {
                            $fail("Tipo de imagem inválido para $attribute.");
                        }
                    },
                ],
            ],

            // 'itens.*.img_file' => 'required_if:itens.*.img_type,file|file|mimes:png,jpeg,jpg',
            // 'itens.*.img_base64' => 'required_if:itens.*.img_type,base64|string',


        );
    }

    public function getbusinessCreditRequest()
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->select(
                'business_credit_requests.id',
                'business_credit_requests.transaction_id',
                'business_credit_requests.credit_reference',
                'business_credit_requests.status', 
                'business_credit_requests.created_at',
                'business_credit_requests.updated_at',
                'dados_solicitantes.name',
                'dados_solicitantes.address',
                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit', // colocar no remaing amount
                'begin_solicitations.total_consumer_value',
                'dados_negocios.business_address',
                'ramo_activities.nome as activity',
                'begin_solicitations.remaing_amount',
                'begin_solicitations.paid_amount',
                'begin_solicitations.request_account',
                'begin_solicitations.provider_account',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        return response()->json(['data' => $business_request], 200);
    }

    // IN_CREATION business solicitation data
    public function getInCreationBusinessCreditRequest()
    {
        // return "IN_CREATION business solicitation";

        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            // ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->leftJoin('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->where('business_credit_requests.status', 'IN_CREATION')
            ->select(
                'business_credit_requests.id',
                'business_credit_requests.transaction_id',
                'business_credit_requests.credit_reference',
                'business_credit_requests.status',
                'business_credit_requests.step',
                'dados_solicitantes.name',
                'dados_solicitantes.address',
                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',
                'dados_negocios.business_address',
                'ramo_activities.nome as activity',
                'business_credit_requests.created_at',
                'business_credit_requests.updated_at',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        return response()->json(['data' => $business_request], 200);
    }

    public function getbusinessCreditRequestPDF(Request $request)
    {
        // $business_request = BusinessCreditRequest::query()
        //     ->where('transaction_id', $request->transaction_id)
        //     ->orWhere('credit_reference', $request->transaction_id)
        //     ->first();

        // if (!$business_request) return SendResponse::errorResp404notfound('Dados não encontrados', 'Data Not Found');

        // return response()->json(['data' => $business_request], 200);

        // $userPayer = User::getUserAccount();
        // if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->with('images')
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->join('agregado_familiars', 'agregado_familiars.id', 'dados_solicitantes.agregado_familiars_id')
            ->join('despesa_mensals', 'despesa_mensals.id', 'dados_solicitantes.despesa_mensals_id')
            // ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->where('business_credit_requests.transaction_id', $request->transaction_id)
            ->orWhere('business_credit_requests.credit_reference', $request->transaction_id)
            ->select(
                'business_credit_requests.*',
                'dados_solicitantes.name',
                'dados_solicitantes.father_name',
                'dados_solicitantes.mother_name',
                'dados_solicitantes.marital_name',
                'dados_solicitantes.phone',
                'dados_solicitantes.alternative_phone',
                'dados_solicitantes.nuit',
                'dados_solicitantes.identity_number',
                'dados_solicitantes.quarter',
                'dados_solicitantes.address',

                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',

                'agregado_familiars.household',
                'agregado_familiars.family_dependents',
                'agregado_familiars.residency_type',
                'despesa_mensals.food',
                'despesa_mensals.rent',
                'despesa_mensals.expenses',
                'despesa_mensals.employee',
                'despesa_mensals.transport',
                'despesa_mensals.education',
                'despesa_mensals.clothes',
                'despesa_mensals.health',
                'despesa_mensals.leisure',
                'despesa_mensals.other',
                'despesa_mensals.other_description',
                'despesa_mensals.total',
                'dados_negocios.business_address',
                'dados_negocios.current_location_antiquity',
                'dados_negocios.antiquity',
                'dados_negocios.other_activities',
                'dados_negocios.monthly_income',
                'ramo_activities.nome as activity',
            )
            ->orderByDesc('business_credit_requests.created_at');
        // ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        $pdf = Pdf::loadView('pdf.exemplo', ['dados' => $business_request]);

        return $pdf->download('documento.pdf');

        // return response()->json(['data' => $business_request], 200);

    }

    public function getbusinessCreditRequestPDFBKP(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->with('images')
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->join('agregado_familiars', 'agregado_familiars.id', 'dados_solicitantes.agregado_familiars_id')
            ->join('despesa_mensals', 'despesa_mensals.id', 'dados_solicitantes.despesa_mensals_id')
            // ->where('business_accounts_id', $userPayer->id)
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->select(
                'business_credit_requests.*',
                'dados_solicitantes.name',
                'dados_solicitantes.father_name',
                'dados_solicitantes.mother_name',
                'dados_solicitantes.marital_name',
                'dados_solicitantes.phone',
                'dados_solicitantes.alternative_phone',
                'dados_solicitantes.nuit',
                'dados_solicitantes.identity_number',
                'dados_solicitantes.quarter',
                'dados_solicitantes.address',

                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',

                'agregado_familiars.household',
                'agregado_familiars.family_dependents',
                'agregado_familiars.residency_type',
                'despesa_mensals.food',
                'despesa_mensals.rent',
                'despesa_mensals.expenses',
                'despesa_mensals.employee',
                'despesa_mensals.transport',
                'despesa_mensals.education',
                'despesa_mensals.clothes',
                'despesa_mensals.health',
                'despesa_mensals.leisure',
                'despesa_mensals.other',
                'despesa_mensals.other_description',
                'despesa_mensals.total',
                'dados_negocios.business_address',
                'dados_negocios.current_location_antiquity',
                'dados_negocios.antiquity',
                'dados_negocios.other_activities',
                'dados_negocios.monthly_income',
                'ramo_activities.nome as activity',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        return response()->json(['data' => $business_request], 200);
    }




    // todo --- EDIT STEP 1 -- CREDIT SOLICITATION

    public function businessCreditRequestEditORIG(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar a solicitação de crédito existente
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->first();

        // return  $credit_request;

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        try {
            DB::beginTransaction();

            // 1️⃣ Atualizar dados do negócio
            if ($credit_request->dados_negocios_id) {
                $dados_negocio = DadosNegocio::find($credit_request->dados_negocios_id);
                if ($dados_negocio) {
                    $dados_negocio->update([
                        'business_address' => $request->business_address ?? $dados_negocio->business_address,
                        'activity_type' => $request->activity_type ?? $dados_negocio->activity_type,
                        'antiquity' => $request->antiquity ?? $dados_negocio->antiquity,
                        'current_location_antiquity' => $request->current_location_antiquity ?? $dados_negocio->current_location_antiquity,
                        'other_activities' => $request->other_activities ?? $dados_negocio->other_activities,
                        'monthly_income' => $request->monthly_income ?? $dados_negocio->monthly_income,
                    ]);
                }
            }

            // 1️⃣ Atualizar dados do negócio
            if ($credit_request->dados_begin_solicitation) {
                $dados_negocio = BeginSolicitation::find($credit_request->dados_begin_solicitation);
                if ($dados_negocio) {
                    $dados_negocio->update([
                        'credit_amount' => $request->credit_amount ?? $dados_negocio->credit_amount,
                        'duration' => $request->duration ?? $dados_negocio->duration,
                        'preparation_fee' => $request->preparation_fee ?? $dados_negocio->preparation_fee,
                        'comission' => $request->comission ?? $dados_negocio->comission,
                        'fee' => $request->fee ?? $dados_negocio->fee,
                        'total_cost_credit' => $request->total_cost_credit ?? $dados_negocio->total_cost_credit,
                        'total_consumer_value' => $request->total_consumer_value ?? $dados_negocio->total_consumer_value,
                    ]);
                }
            }

            // 2️⃣ Atualizar dados principais da solicitação
            $credit_request->update([
                // 'credit_reference' => $request->credit_reference ?? $credit_request->credit_reference,
                'document_type' => $request->document_type ?? $credit_request->document_type,
                'document_file' => $request->document_file ?? $credit_request->document_file,
                'declaration_market' => $request->declaration_market ?? $credit_request->declaration_market,
                'photo_market' => $request->photo_market ?? $credit_request->photo_market,
            ]);

            // 3️⃣ Atualizar imagens, se houver novos uploads
            $this->uploadImages($request, $credit_request);

            DB::commit();

            return response()->json([
                'message' => 'Solicitação de Crédito atualizada com sucesso',
                'data' => $credit_request->fresh()
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return response()->json(['message' => 'Falha ao atualizar a solicitação de crédito', 'error' => $th->getMessage()], 500);
        }
    }


    public function businessCreditRequestEditVOLTO(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar a solicitação de crédito existente
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->where('step', 1)
            ->where('status', 'IN_CREATION')
            ->first();

        $begin_solicitation_data = BeginSolicitation::find($credit_request->dados_begin_solicitation);

        $dados_negocio = DadosNegocio::find($credit_request->dados_negocios_id);

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        return $credit_request . '--' . $begin_solicitation_data . '--' . $dados_negocio;

        // 1️⃣ Atualizar dados do negócio
        if ($credit_request->dados_negocios_id) {
            $dados_negocio = DadosNegocio::find($credit_request->dados_negocios_id);
            if ($dados_negocio) {
                $dados_negocio->update([
                    'business_address' => $request->business_address ?? $dados_negocio->business_address,
                    'activity_type' => $request->activity_type ?? $dados_negocio->activity_type,
                    'antiquity' => $request->antiquity ?? $dados_negocio->antiquity,
                    'current_location_antiquity' => $request->current_location_antiquity ?? $dados_negocio->current_location_antiquity,
                    'other_activities' => $request->other_activities ?? $dados_negocio->other_activities,
                    'monthly_income' => $request->monthly_income ?? $dados_negocio->monthly_income,
                ]);
            }
        }

        return response()->json([
            'message' => 'Solicitação de Crédito actualizada com sucesso',
            'data' => $credit_request->fresh()
        ]);
    }

    // todo -- new 13/11/2025 🦺 NIVEL I
    public function businessCreditRequestEdit(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar solicitação de crédito
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            // ->where('step', 1)
            ->where('step', $request->step)
            ->where('status', 'IN_CREATION')
            ->first();

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        // Buscar dados relacionados
        $begin_solicitation_data = BeginSolicitation::find($credit_request->dados_begin_solicitation);
        $dados_negocio = DadosNegocio::find($credit_request->dados_negocios_id);
        $dados_solicitante = DadosSolicitante::find($credit_request->dados_solicitantes_id);

        // Atualizar BusinessCreditRequest ✅
        $credit_request->update([
            'status' => $credit_request->status,
            'step' => $credit_request->step,
            'document_type' => $request->document_type ?? $credit_request->document_type,

            'document_file' => $request->document_file ?? $credit_request->document_file,
            'declaration_market' => $request->declaration_market ?? $credit_request->declaration_market,
            'photo_market' => $request->photo_market ?? $credit_request->photo_market,

            'dados_begin_solicitation' => $credit_request->dados_begin_solicitation,
            'dados_negocios_id' => $credit_request->dados_negocios_id,
            'dados_solicitantes_id' => $credit_request->dados_solicitantes_id,
            'credit_reference' => $credit_request->credit_reference
        ]);

        // 3️⃣ Atualizar imagens, se houver novos uploads
        $this->uploadImages($request, $credit_request);

        // Atualizar BeginSolicitation ✅
        if ($begin_solicitation_data) {
            $begin_solicitation_data->update([
                'credit_amount' => $request->credit_amount ?? $begin_solicitation_data->credit_amount,
                'duration' => $request->duration ?? $begin_solicitation_data->duration,
                'fee' => $request->fee ?? $begin_solicitation_data->fee,
                'total_cost_credit' => $request->total_cost_credit ?? $begin_solicitation_data->total_cost_credit,
                'request_account' => $request->request_account ?? $begin_solicitation_data->request_account,
                'provider_account' => $request->provider_account ?? $begin_solicitation_data->provider_account,
                'provider_id' => $request->provider_id ?? $begin_solicitation_data->provider_id,
            ]);
        }

        // Actualizar DadosNegocio ✅
        if ($dados_negocio) {
            $dados_negocio->update([
                'business_address' => $request->business_address ?? $dados_negocio->business_address,
                'activity_type' => $request->activity_type ?? $dados_negocio->activity_type,
                'antiquity' => $request->antiquity ?? $dados_negocio->antiquity,
                'current_location_antiquity' => $request->current_location_antiquity ?? $dados_negocio->current_location_antiquity,
                'other_activities' => $request->other_activities ?? $dados_negocio->other_activities,
                'monthly_income' => $request->monthly_income ?? $dados_negocio->monthly_income,
            ]);
        }

        // Atualizar Solicitante ✅
        if ($dados_solicitante) {
            $dados_solicitante->update([
                'name' => $request->name ?? $dados_solicitante->name,
                'father_name' => $request->father_name ?? $dados_solicitante->father_name,
                'mother_name' => $request->mother_name ?? $dados_solicitante->mother_name,
                'marital_status' => $request->marital_status ?? $dados_solicitante->marital_status,
                'marital_name' => $request->marital_name ?? $dados_solicitante->marital_name,
                'phone' => $request->phone ?? $dados_solicitante->phone,
                'alternative_phone' => $request->alternative_phone ?? $dados_solicitante->alternative_phone,
                'nuit' => $request->nuit ?? $dados_solicitante->nuit,
                'identity_number' => $request->identity_number ?? $dados_solicitante->identity_number,
                'province_id' => $request->province_id ?? $dados_solicitante->province_id,
                'quarter' => $request->quarter ?? $dados_solicitante->quarter,
                'address' => $request->address ?? $dados_solicitante->address,
            ]);
        }

        return response()->json([
            'message' => 'Solicitação de crédito actualizada com sucesso',
            'data' => [
                'credit_request' => $credit_request->fresh(),
                'begin_solicitation' => $begin_solicitation_data ? $begin_solicitation_data->fresh() : null,
                'dados_negocio' => $dados_negocio ? $dados_negocio->fresh() : null,
                'dados_solicitante' => $dados_solicitante ? $dados_solicitante->fresh() : null,
            ]
        ]);
    }

    // todo -- new 13/11/2025 🦺 NIVEL II
    public function businessCreditRequestEditII(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar solicitação de crédito
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            // ->where('step', 2)
            ->where('step', $request->step)
            ->where('status', 'IN_CREATION')
            ->first();

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        // Buscar dados relacionados
        $dados_solicitante = DadosSolicitante::find($credit_request->dados_solicitantes_id);
        // return $dados_solicitante;

        $agregado_familiar = AgregadoFamiliar::find($dados_solicitante->agregado_familiars_id);
        // return $agregado_familiar;
        $despesas_mensais = DespesaMensal::find($dados_solicitante->despesa_mensals_id);
        // return $despesas_mensais;

        // Atualizar BeginSolicitation ✅
        if ($agregado_familiar) {
            $agregado_familiar->update([
                'household' => $request->household ?? $agregado_familiar->household,
                'family_dependents' => $request->family_dependents ?? $agregado_familiar->family_dependents,
                'residency_type' => $request->residency_type ?? $agregado_familiar->residency_type,
                'business_accounts_id' => $agregado_familiar->business_accounts_id
            ]);
        }

        // Actualizar Despesas Mensais ✅
        if ($despesas_mensais) {
            $despesas_mensais->update([
                'food' => $request->food ?? $despesas_mensais->food,
                'rent' => $request->rent ?? $despesas_mensais->rent,
                'expenses' => $request->expenses ?? $despesas_mensais->expenses,
                'employee' => $request->employee ?? $despesas_mensais->employee,
                'transport' => $request->transport ?? $despesas_mensais->transport,
                'education' => $request->education ?? $despesas_mensais->education,
                'clothes' => $request->clothes ?? $despesas_mensais->clothes,
                'health' => $request->health ?? $despesas_mensais->health,
                'leisure' => $request->leisure ?? $despesas_mensais->leisure,
                'other' => $request->other ?? $despesas_mensais->other,
                'other_description' => $request->other_description ?? $despesas_mensais->other_description,
                'total' => $request->total ?? $despesas_mensais->total,
                'business_accounts_id' => $despesas_mensais->business_accounts_id
            ]);
        }

        return response()->json([
            'message' => 'Solicitação de crédito actualizada com sucesso',
            'data' => [
                'agregado_familiar' => $agregado_familiar->fresh(),
                'despesas_mensais' => $despesas_mensais ? $despesas_mensais->fresh() : null,
                // 'dados_negocio' => $dados_negocio ? $dados_negocio->fresh() : null,
            ]
        ]);
    }

    // todo -- new 13/11/2025 🦺 NIVEL III
    public function businessCreditRequestEditIII(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar solicitação de crédito
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            // ->where('step', 3)
            ->where('step', $request->step)
            ->where('status', 'IN_CREATION')
            // ->whereIn('status', ['PENDING', 'IN_CREATION'])
            ->first();

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        // return $credit_request;

        try {
            DB::beginTransaction();

            // Atualiza os parâmetros principais
            $this->business_credit_params($request);

            // Atualiza os ficheiros de garantia (warrenty items)
            $this->businessRequestWarrentyEdit($request, $userPayer, $credit_request);

            // Atualiza o status se necessário
            $credit_request->update([
                'status' => 'PENDING',
                'updated_at' => now(),
            ]);

            DB::commit();

            return response()->json(['message' => 'Dados da solicitação de crédito actualizados com sucesso!'], 200);
        } catch (\Throwable $th) {
            DB::rollBack();
            return response()->json([
                'message' => 'Falha ao atualizar os dados da solicitação',
                'error' => $th->getMessage()
            ], 500);
        }
    }

    // todo -- new 13/11/2025 🦺
    private function businessRequestWarrentyEdit($request, $userPayer, $credit_request)
    {
        $img_uploader = new ImageUploader();
        $new_items = [];

        foreach ($request->itens as $index => $item) {
            // Caso haja upload novo
            if ($request->hasFile('itens.' . $index . '.img')) {
                $item['img'] = $img_uploader->generateImageUrlName25($request, 'itens.' . $index . '.img', 'documentos/', 11);
            } elseif (!empty($item['img'])) {
                // Mantém o link antigo se não foi alterado
                $item['img'] = $item['img'];
            } else {
                continue; // Ignora itens sem imagem
            }

            $item['business_accounts_id'] = $userPayer->account_id;
            $item['updated_at'] = now();
            unset($item['img_type']);

            array_push($new_items, $item);
        }

        try {
            // Atualiza os itens (mantendo os IDs existentes)
            $credit_request->items()->sync($new_items);
            return true;
        } catch (\Throwable $th) {
            throw new \Exception("Erro ao atualizar garantias: " . $th->getMessage());
        }
    }


    // todo -- new 13/11/2025 🦺
    public function destroy_credit_request(Request $request)
    {

        $this->validate($request, [
            'transaction_id' => 'required|string',
        ]);

        $userPayer = User::getUserAccount();
        if (!$userPayer) {
            return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');
        }

        // Buscar solicitação de crédito
        $credit_request = BusinessCreditRequest::where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            // ->where('step', 3)
            ->where('status', 'IN_CREATION')
            // ->whereIn('status', ['PENDING', 'IN_CREATION'])
            ->first();

        if (!$credit_request) {
            return response()->json(['message' => 'Solicitação de crédito não encontrada'], 404);
        }

        // return $credit_request;

        try {
            DB::beginTransaction();

            // 🔹 Buscar os IDs relacionados
            $dados_begin_id = $credit_request->dados_begin_solicitation;
            // return $dados_begin_id;

            $dados_negocio_id = $credit_request->dados_negocios_id;
            // return $dados_negocio_id;

            $dados_solicitante_id = $credit_request->dados_solicitantes_id;
            // return $dados_solicitante_id;

            // 🔹 Apagar garantias associadas à solicitação
            BusinessRequestWarrentyFile::where('request_id', $credit_request->id)->delete();

            // 🔹 Eliminar dependências do solicitante
            if ($dados_solicitante_id) {
                $dados_solicitante = DadosSolicitante::find($dados_solicitante_id);
                if ($dados_solicitante) {
                    // Eliminar agregado familiar
                    if ($dados_solicitante->agregado_familiars_id) {
                        AgregadoFamiliar::where('id', $dados_solicitante->agregado_familiars_id)->delete();
                    }

                    // Eliminar despesa mensal
                    if ($dados_solicitante->despesa_mensals_id) {
                        DespesaMensal::where('id', $dados_solicitante->despesa_mensals_id)->delete();
                    }

                    // Eliminar o próprio solicitante
                    $dados_solicitante->delete();
                }
            }

            // 🔹 Eliminar BeginSolicitation e DadosNegocio
            if ($dados_begin_id) {
                BeginSolicitation::where('id', $dados_begin_id)->delete();
            }

            if ($dados_negocio_id) {
                DadosNegocio::where('id', $dados_negocio_id)->delete();
            }

            // 🔹 Por fim, eliminar a solicitação principal
            $credit_request->delete();

            DB::commit();

            return response()->json([
                'message' => 'Solicitação de crédito e dados associados eliminados com sucesso.'
            ], 200);
        } catch (\Throwable $th) {
            DB::rollBack();
            return response()->json([
                'message' => 'Erro ao eliminar os dados: ' . $th->getMessage()
            ], 500);
        }
    }




    // public function get_credit_solicitation()
    // {
    //     $size = (!request()->per_page) ? 4 : request()->per_page;

    //     $business = BusinessAccount::where('user_id', auth()->user()->id)->first();

    //     if (!$business) {
    //         return "CONTA EMPRESA NAO ENCONTRADA";
    //     }

    //     // Verificar se aceita crédito
    //     if ($business->accept_loans == 1) {

    //         // Buscar todas as solicitações de crédito com status PENDING
    //         $pendingSolicitations = BusinessCreditRequest::where('status', 'PENDING')
    //             ->where('transaction_id', request()->transaction_id)
    //             ->orderByDesc('created_at')
    //             // ->get();
    //             ->paginate($size);

    //         return response()->json([
    //             'status' => true,
    //             // 'message' => 'A CONTA ACEITA SOLICITACAO DE CREDITO.',
    //             'message' => 'SOLICITAÇÕES DE CRÉDITO.',
    //             'data' => $pendingSolicitations
    //         ]);
    //     } else {
    //         return response()->json([
    //             'status' => false,
    //             'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
    //         ]);
    //     }
    // }

    // Updated 🔄
    public function get_credit_solicitationCORRECT(Request $request)
    {
        $size = $request->per_page ?? 4;

        // Buscar conta da empresa do usuário autenticado
        // $business = BusinessAccount::where('user_id', auth()->user()->id)->first();
        $business = User::getUserDetails(auth()->user()->user_id);

        if (!$business) {
            return response()->json([
                'status' => false,
                'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
            ], 404);
        }

        // Verificar se a conta aceita crédito
        if ($business->accept_loans != 1) {
            return response()->json([
                'status' => false,
                'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
            ], 403);
        }

        // Definir o status padrão (PENDING)
        $status = $request->status ?? 'PENDING';

        // Montar query base com status
        $query = BusinessCreditRequest::where('status', $status)
            ->orderByDesc('created_at');

        // Filtrar opcionalmente por transaction_id
        if ($request->filled('transaction_id')) {
            $query->where('transaction_id', $request->transaction_id);
        }

        // Paginar os resultados
        $solicitations = $query->paginate($size);

        // Retornar resposta
        return response()->json([
            'status' => true,
            'message' => 'SOLICITAÇÕES DE CRÉDITO.',
            'data' => $solicitations
        ]);
    }


    public function get_credit_solicitation(Request $request)
    {
        $size = $request->per_page ?? 4;

        // Buscar conta da empresa do usuário autenticado
        $business = User::getUserDetails(auth()->user()->user_id);

        if (!$business) {
            return response()->json([
                'status' => false,
                'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
            ], 404);
        }

        // Verificar se a conta aceita crédito
        if ($business->accept_loans != 1) {
            return response()->json([
                'status' => false,
                'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
            ], 403);
        }

        // Obter status (padrão: PENDING)
        $status = strtoupper($request->status ?? 'PENDING');

        // Montar query base
        $query = BusinessCreditRequest::without('business_account')
            ->join('begin_solicitations', 'begin_solicitations.id', '=', 'business_credit_requests.dados_begin_solicitation')
            ->join('business_accounts', 'business_accounts.id', '=', 'business_credit_requests.business_accounts_id')
            ->join('users', 'users.id', '=', 'business_accounts.user_id')
            ->select([
                'business_credit_requests.id',
                'business_credit_requests.transaction_id',
                'business_credit_requests.credit_reference',
                'business_credit_requests.business_accounts_id',
                'business_credit_requests.document_type',
                'business_credit_requests.document_file',
                'business_credit_requests.declaration_market',
                'business_credit_requests.photo_market',
                'business_credit_requests.dados_begin_solicitation',
                'business_credit_requests.dados_negocios_id',
                'business_credit_requests.dados_solicitantes_id',
                'business_credit_requests.status',
                'business_credit_requests.step',
                'business_credit_requests.rejected_reason',
                'business_credit_requests.created_at',
                'business_credit_requests.updated_at',
                'begin_solicitations.credit_amount as amount',
                'begin_solicitations.fee',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.remaing_amount',
                'begin_solicitations.paid_amount',
                'business_accounts.account_number as account_number',
                'users.name',
                'users.phone',
                'users.email',
            ])
            ->orderByDesc('business_credit_requests.created_at');

        // Aplicar filtros de status
        if ($status === 'ALL') {
            $query->where('business_credit_requests.status', '!=', 'IN_CREATION');
        } else {
            $query->where('business_credit_requests.status', $status);
        }

        // Filtrar por transaction_id, se fornecido
        if ($request->filled('transaction_id')) {
            $query->where('transaction_id', $request->transaction_id);
        }

        // Paginar resultados
        $solicitations = $query->paginate($size);

        // Retornar resposta formatada
        return response()->json([
            'status' => true,
            'message' => $status === 'ALL'
                ? 'TODAS AS SOLICITAÇÕES DE CRÉDITO.'
                : "SOLICITAÇÕES DE CRÉDITO COM STATUS {$status}.",
            'data' => $solicitations
        ]);
    }


    public function get_credit_solicitation03(Request $request)
    {
        $size = $request->per_page ?? 4;

        // Buscar conta da empresa do usuário autenticado
        $business = User::getUserDetails(auth()->user()->user_id);

        if (!$business) {
            return response()->json([
                'status' => false,
                'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
            ], 404);
        }

        // Verificar se a conta aceita crédito
        if ($business->accept_loans != 1) {
            return response()->json([
                'status' => false,
                'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
            ], 403);
        }

        // Obter status (padrão: PENDING)
        $status = strtoupper($request->status ?? 'PENDING');

        // Montar query base
        // $query = BusinessCreditRequest::query()
        //     ->select('business_credit_requests.*', 'begin_solicitations.credit_amount')
        //     ->orderByDesc('created_at');

        // CODIGO ORIGINAL
        //$query = BusinessCreditRequest::query()
        //    ->join('begin_solicitations', 'begin_solicitations.id', '=', 'business_credit_requests.dados_begin_solicitation')
        //    ->select('business_credit_requests.*', 'begin_solicitations.credit_amount as amount')
        //    ->orderByDesc('business_credit_requests.created_at');

        // CODIGO NOVO
        $query = BusinessCreditRequest::query()
            ->join('begin_solicitations', 'begin_solicitations.id', '=', 'business_credit_requests.dados_begin_solicitation')
            ->join('dados_solicitantes', 'dados_solicitantes.id', '=', 'business_credit_requests.dados_solicitantes_id')
            ->join('business_accounts', 'business_accounts.id', '=', 'business_credit_requests.business_accounts_id')
            ->join('users', 'users.id', '=', 'business_accounts.user_id') // associação com o user principal
            ->select(
                'business_credit_requests.*',
                'begin_solicitations.credit_amount as amount',
                'business_accounts.account_number',
                'users.name as name',
                'users.phone as phone',
                'users.email as email'
            )
            ->orderByDesc('business_credit_requests.created_at');


        // Se o status não for "ALL", aplicar filtro de status
        // if ($status !== 'ALL') {
        //     $query->where('status', $status);
        // }

        // Aplicar filtros de status
        if ($status === 'ALL') {
            // Excluir apenas as solicitações com status IN_CREATION
            //$query->where('status', '!=', 'IN_CREATION');
            $query->where('business_credit_requests.status', '!=', 'IN_CREATION');
        } else {
            // Mostrar apenas as solicitações com o status informado
            //$query->where('status', $status);
            $query->where('business_credit_requests.status', $status);
        }

        // Filtrar opcionalmente por transaction_id
        if ($request->filled('transaction_id')) {
            $query->where('transaction_id', $request->transaction_id);
        }

        // Paginar resultados
        $solicitations = $query->paginate($size);
        // Ocultar campo 'business_account' da coleção
        //$solicitations->getCollection()->makeHidden(['business_account']);
        // Remover o bloco "business_account" de cada item
        $solicitations->getCollection()->transform(function ($item) {
            if (isset($item->business_account)) {
                unset($item->business_account);
            }
            return $item;
        });

        // Retornar resposta
        return response()->json([
            'status' => true,
            'message' => $status === 'ALL'
                ? 'TODAS AS SOLICITAÇÕES DE CRÉDITO.'
                : "SOLICITAÇÕES DE CRÉDITO COM STATUS {$status}.",
            'data' => $solicitations
        ]);
    }


    public function update_credit_solicitation(Request $request)
    {

        // Buscar conta da empresa do usuário autenticado
        $business = User::getUserDetails(auth()->user()->user_id);

        if (!$business) {
            return response()->json([
                'status' => false,
                'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
            ], 404);
        }

        // Verificar se a conta aceita crédito
        if ($business->accept_loans != 1) {
            return response()->json([
                'status' => false,
                'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
            ], 403);
        }

        // Validar os parâmetros recebidos
        $request->validate([
            'id' => 'nullable|integer',
            'transaction_id' => 'required|string',
            'status' => 'required|string',
        ]);

        // Garantir que pelo menos um parâmetro seja enviado
        if (!$request->id && !$request->transaction_id) {
            return response()->json([
                'status' => false,
                'message' => 'É necessário informar o ID ou o Transaction ID da solicitação.'
            ], 400);
        }

        // Buscar a solicitação de crédito
        $creditRequest = BusinessCreditRequest::query()
            ->where('transaction_id', $request->transaction_id)
            ->orWhere('id', $request->id)
            ->first();

        // Verificar se existe e se está PENDING
        if (!$creditRequest) {
            return response()->json([
                'status' => false,
                'message' => 'Nenhuma solicitação PENDING encontrada com os dados fornecidos.'
            ], 404);
        }

        // Caso esteja PENDING → muda para UNDER_EVALUATION
        if (($request->status === 'UNDER_EVALUATION') && ($creditRequest->status === 'PENDING')) {
            $creditRequest->update(['status' => 'UNDER_EVALUATION']);

            return response()->json([
                'status' => true,
                'message' => 'Solicitação está em avaliação.',
                'data' => $creditRequest
            ]);
        }

        // Caso esteja PENDING → muda para UNDER_EVALUATION
        if (($request->status === 'APPROVED') && ($creditRequest->status === 'UNDER_EVALUATION')) {
            $request->validate([
                'credit_reference' => 'required|string',
            ]);

            $creditRequest->update([
                'status' => $request->status, # APPROVED
                'credit_reference' => $request->credit_reference,
            ]);

            return response()->json([
                'status' => true,
                'message' => 'Solicitação de crédito aprovada com sucesso.',
                'data' => $creditRequest
            ]);
        }

        // Caso esteja PENDING → muda para UNDER_EVALUATION
        if (($request->status === 'REJECTED') && ($creditRequest->status === 'UNDER_EVALUATION')) {
            $request->validate([
                'rejected_reason' => 'required|string',
            ]);

            $creditRequest->update([
                'status' => $request->status, # APPROVED
                'rejected_reason' => $request->rejected_reason,
            ]);

            return response()->json([
                'status' => true,
                'message' => 'Solicitação de crédito aprovada com sucesso.',
                'data' => $creditRequest
            ]);
        } else {
            return response()->json([
                'status' => false,
                'message' => 'Transação inválida.',
                // 'data' => $creditRequest
            ]);
        }
    }
}