<?php

namespace App\Http\Controllers\admin;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Validation\ValidationException;
use App\Services\{ImagesServices,SalesDebtServices,PaysServices};
use App\Models\{Pay, Bank, Pay_type,Membership_users};
use App\Traits\{GetModelsPaginated,GetCompanyInfo};
use function fit_config; // Importar el helper
class paysController extends Controller
{
    protected $paysServices;
    protected $salesDebtServices;
    public $daysMaxFree= 2;
    use GetCompanyInfo;
    use GetModelsPaginated;
    public function __construct(PaysServices $paysServices, SalesDebtServices $salesDebtServices)
    {
        $this->paysServices = $paysServices;
        $this->salesDebtServices = $salesDebtServices;
    }
    public function index()
    {
        return view('admin.pay.index');
    }
    public function payPaginatedJson(Request $request)
    {
        return $this->paginateFromService(
            $request,
            function (int $page, int $length, ?string $searchValue, ?string $status) use ($request) {
                $dateFrom = $request->input('date_from');
                $dateTo = $request->input('date_to');
                return $this->paysServices->getPaysData($page, $length, $searchValue, $status, $dateFrom, $dateTo);
            }
        );
    }
    public function create(Request $request)
    {
        $banks = Bank::orderBy('name')->get();
        $userId = Auth::id();
        $userSelected = $request->query('user_id') ?? 0;
        $selectedPayDate = $request->query('pay_date');
        $isFullInput = (int) $request->query('is_full_input', 1) === 1;
        $companyInfo = $request->attributes->get('companyInfo') ?? $this->getCompanyInfo($userId);
        $companyId = $companyInfo ? $companyInfo->id : null;

        $maxDaysForPay = fit_config('max_days_for_pay', 10);
          // Calcular fecha mínima (hoy - maxDaysForPay días)
        $minPayDate = now()->subDays($maxDaysForPay)->format('Y-m-d');
        $todayDate = now()->format('Y-m-d');
        if (! empty($userSelected)) {
            $today = date('Y-m-d');

            if (! empty($selectedPayDate) && $selectedPayDate !== $today) {
                // Fecha distinta de hoy: usar tasa histórica de esa fecha.
                app(\App\Services\SalesService::class)->setNewRateToDebtSales((int) $userSelected, (string) $selectedPayDate);
            } else {
                // Hoy (o sin fecha explícita): usar la tasa activa.
                app(\App\Services\SalesService::class)->setNewRateToDebtSales((int) $userSelected);
            }
        }
        $listUserDebts = $this->salesDebtServices->getIdUserDebt(null, $companyId);
        //deudas del usuario seleccionado
        $debts = $this->salesDebtServices->getUserDebt($userSelected, $companyId, true);

        // Si se usa AssistanceServices para registrar asistencia, pasar el límite daysMaxFree
        // Ejemplo de uso:
        // app(\App\Services\AssistanceServices::class)->createAssistance([...], null, $this->daysMaxFree);

       // print("<pre style='background-color: #f0f0f0; padding: 10px;'> debts debts: ".print_r($debts, true)."</pre>");

        $pay_typeSeeder = Pay_type::where('company_id', $companyId)->where('is_active', 1)->get();
        $membership_users = membership_users::with('membership')->where('user_id', Auth::id())->first();
        return view('admin.pay.create', compact('banks', 'membership_users', 'pay_typeSeeder', 'debts', 'listUserDebts', 'userSelected', 'selectedPayDate', 'isFullInput', 'maxDaysForPay','minPayDate', 'todayDate'));
    }
    public function edit(Pay $pay)
    {
        $pay->loadMissing([
            'user.people',
            'payDetails.sale.saleDetails.product',
            'payDetails.sale.saleDetails.membershipUser.membership',
        ]);

        $banks = Bank::orderBy('name')->get();
        $pay_typeSeeder = Pay_type::query()
            ->where('company_id', $pay->company_id)
            ->where(function ($query) use ($pay): void {
                $query->where('is_active', 1)
                    ->orWhere('id', $pay->pay_type_id);
            })
            ->orderBy('name')
            ->get();

        $debts = $this->salesDebtServices->getUserDebt($pay->user_id, $pay->company_id, true) ?? collect();
        $detailsTotal = (float) $pay->payDetails->sum('amount');
        $remainingAmount = (float) $pay->amount - $detailsTotal;

        return view('admin.pay.edit', compact('pay', 'banks', 'pay_typeSeeder', 'debts', 'detailsTotal', 'remainingAmount'));
    }
    public function store(Request $request)
    {
        $authUserId = Auth::id();
        $selectedUserId = $request->input('user_id');
        $isFullInput = $request->has('is_full_input') && $request->input('is_full_input') ? true : false;

        $rules = [
            'pay_type_id' => 'required|integer|exists:pay_type,id',
            'pay_date' => 'required|date',
            'amount' => 'required',
            'status' => 'required|string|in:Aprobado,Rechazado,Pendiente',
        ];

        $isCashPayment = $this->paysServices->isCashPayTypeId((int) $request->input('pay_type_id'));

        if ($isFullInput) {
            $rules['bank_id'] = $isCashPayment ? 'nullable|integer|exists:bank,id' : 'required|integer|exists:bank,id';
            $rules['reference'] = 'required|string|max:100';
            $rules['id_card_number'] = 'required|string|max:50';
            $rules['url_pay_imagen'] = 'required|image|max:4096';
        } else {
            $rules['bank_id'] = $isCashPayment ? 'nullable|integer|exists:bank,id' : 'required|integer|exists:bank,id';
            $rules['reference'] = 'nullable|string|max:100';
            $rules['id_card_number'] = 'nullable|string|max:50';
            $rules['url_pay_imagen'] = 'nullable|image|max:4096';
        }

        $request->validate($rules);

        if ($selectedUserId === null || $selectedUserId === '') {
            throw ValidationException::withMessages([
                'user_id' => 'Debes seleccionar un usuario para registrar el pago.',
            ]);
        }

        $companyInfo = $request->attributes->get('companyInfo') ?? $this->getCompanyInfo($authUserId);
        $companyId = $companyInfo ? $companyInfo->id : null;

        try {
            $status = $request->input('status', 'Pendiente');
            // Añadir is_full_input al request para que se guarde en el modelo
            $request->merge(['is_full_input' => $isFullInput]);
            $this->paysServices->storeSomesPay($request, (int) $selectedUserId, (int) $companyId, $status);

            return redirect()->route('admin_fit.pay.index')->with('success', 'Pago creado exitosamente.');
        } catch (ValidationException $e) {
            throw $e;
        } catch (\Exception $e) {
            return redirect()->back()->withErrors(['error' => 'Error al registrar el pago: ' . $e->getMessage()])->withInput();
        }
    }
public function update(Request $request, $pay)
{
    // Normalizar el monto antes de validar
    if ($request->has('amount')) {
        $normalizedAmount = $this->normalizeDecimalInput($request->input('amount'));
        $request->merge(['amount' => $normalizedAmount]);
    }
    
    // También normalizar montos en sale_amounts si existen
    if ($request->has('sale_amounts') && is_array($request->input('sale_amounts'))) {
        $saleAmounts = $request->input('sale_amounts');
        foreach ($saleAmounts as $saleId => $amount) {
            if (is_string($amount) && !empty($amount)) {
                $saleAmounts[$saleId] = $this->normalizeDecimalInput($amount);
            }
        }
        $request->merge(['sale_amounts' => $saleAmounts]);
    }
    
    $this->paysServices->updatePay($request, $pay);
    return redirect()->route('admin_fit.pay.index')->with('success', 'Pago actualizado exitosamente.');
}
private function normalizeDecimalInput($value): float
{
    if (empty($value)) {
        return 0;
    }
    
    $value = trim((string) $value);
    
    // Eliminar puntos de miles y convertir coma decimal a punto
    // Detectar si tiene formato con miles (puntos) y decimales (coma)
    $hasThousandsDot = substr_count($value, '.') > 0;
    $hasDecimalComma = strpos($value, ',') !== false;
    
    if ($hasThousandsDot && $hasDecimalComma) {
        // Formato: 22.000,00 -> quitar puntos, cambiar coma por punto
        $value = str_replace('.', '', $value);
        $value = str_replace(',', '.', $value);
    } elseif ($hasDecimalComma) {
        // Solo coma: 22000,00 -> cambiar coma por punto
        $value = str_replace(',', '.', $value);
    }
    
    // Eliminar cualquier caracter que no sea número o punto
    $value = preg_replace('/[^0-9.-]/', '', $value);
    
    return (float) $value;
}

    public function image(string $filename)
    {
        $imagePath = storage_path('app/public/pay/large/' . $filename);

        if (! File::exists($imagePath)) {
            $imagePath = storage_path('app/public/pay/small/' . $filename);
        }

        if (! File::exists($imagePath)) {
            $imagePath = public_path('images/no-user-imagen.jpg');
        }

        return response()->file($imagePath);
    }

        /**
     * Exportar pagos filtrados a Excel
     */
    public function export(Request $request)
    {
        // Campos exportables y sus etiquetas
        $exportFields = [
            'status' => 'Estado',
            'user_name' => 'Nombre',
            'pay_type_name' => 'Tipo de Pago',
            'bank_name' => 'Banco',
            'amount' => 'Monto',
            'reference' => 'Referencia',
            'pay_date_formatted' => 'Fecha de Creación',
        ];

        $selectedFields = $request->input('fields', array_keys($exportFields));
        $searchValue = $request->input('search_value');
        $status = $request->input('status');
            $dateFrom = $request->input('date_from');
            $dateTo = $request->input('date_to');

            $rows = $this->paysServices->getPaysExportData($searchValue, $status, $dateFrom, $dateTo);

        // Usar ExcelServices para exportar
        $excel = app(\App\Services\ExcelServices::class);
        return $excel->downloadGenericExcel('pagos.xls', $exportFields, $selectedFields, $rows);
    }
}
