<?php

namespace App\Http\Controllers;

use App\Models\Usuario;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class DatosBancariosController extends Controller
{
    /**
     * Obtener datos bancarios del usuario
     */
    public function mostrar($usuarioId)
    {
        $usuario = Usuario::findOrFail($usuarioId);

        $cuenta = $this->formatearCuenta($usuario);

        if (!$cuenta) {
            return response()->json([
                'success' => true,
                'data' => [],
                'message' => 'El usuario no tiene cuentas bancarias registradas'
            ]);
        }

        return response()->json([
            'success' => true,
            'data' => [$cuenta]
        ]);
    }

    /**
     * Registrar o actualizar datos bancarios del usuario
     */
    public function guardar(Request $request, $usuarioId)
    {
        $usuario = Usuario::findOrFail($usuarioId);

        $validated = $request->validate([
            'banco' => 'required|string|max:100',
            'tipo_cuenta' => 'required|in:ahorros,corriente',
            'numero_cuenta' => ['required', 'regex:/^\d{10,20}$/'],
            'titular' => 'sometimes|nullable|string|max:255',
            'es_principal' => 'nullable',
            'certificado_bancario' => 'nullable|file|mimes:pdf,jpg,jpeg,png,heic|max:5120'
        ]);

        $esPrincipal = filter_var(
            $request->input('es_principal', true),
            FILTER_VALIDATE_BOOLEAN,
            FILTER_NULL_ON_FAILURE
        );

        if ($esPrincipal === null) {
            $esPrincipal = true;
        }

        $data = [
            'banco' => $validated['banco'],
            'tipo_cuenta' => $validated['tipo_cuenta'],
            'numero_cuenta' => $validated['numero_cuenta'],
            'datos_bancarios_verificados_at' => null,
        ];

        if ($request->hasFile('certificado_bancario')) {
            $file = $request->file('certificado_bancario');
            $path = $file->store("certificados/user-{$usuarioId}", 'public');

            $data['certificado_bancario'] = $path;

            $this->registrarDocumentoCertificado($usuarioId, $path, $file->getSize());
        }

        $usuario->update($data);

        $cuenta = $this->formatearCuenta($usuario->fresh());

        if ($cuenta) {
            $cuenta['es_principal'] = $esPrincipal;
        }

        return response()->json([
            'success' => true,
            'message' => 'Datos bancarios guardados correctamente',
            'data' => $cuenta
        ], 201);
    }

    /**
     * Obtener información de las fotos de la cédula
     */
    public function cedula($usuarioId)
    {
        $usuario = Usuario::findOrFail($usuarioId);

        $datos = $this->formatearCedula($usuario);

        return response()->json([
            'success' => true,
            'data' => $datos
        ]);
    }

    /**
     * Subir fotos de la cédula
     */
    public function subirCedula(Request $request, $usuarioId)
    {
        $usuario = Usuario::findOrFail($usuarioId);

        $validated = $request->validate([
            'cedula_frente' => 'required|image|mimes:jpg,jpeg,png,heic|max:10240',
            'cedula_atras' => 'required|image|mimes:jpg,jpeg,png,heic|max:10240'
        ]);

        $frentePath = $request->file('cedula_frente')->store("cedulas/user-{$usuarioId}", 'public');
        $atrasPath = $request->file('cedula_atras')->store("cedulas/user-{$usuarioId}", 'public');

        $usuario->update([
            'cedula_foto_frente' => $frentePath,
            'cedula_foto_atras' => $atrasPath,
            'cedula_verificada_at' => null
        ]);

        $datos = $this->formatearCedula($usuario->fresh());

        return response()->json([
            'success' => true,
            'message' => 'Fotos de cédula subidas correctamente',
            'data' => $datos
        ], 201);
    }

    private function formatearCuenta(Usuario $usuario): ?array
    {
        if (!$usuario->banco || !$usuario->numero_cuenta) {
            return null;
        }

        $numeroCuenta = (string) $usuario->numero_cuenta;
        $parcial = Str::length($numeroCuenta) >= 4
            ? '****' . Str::substr($numeroCuenta, -4)
            : $numeroCuenta;

        $certificadoPath = $usuario->certificado_bancario;
        $certificadoUrl = null;

        if ($certificadoPath) {
            $certificadoUrl = Storage::disk('public')->url($certificadoPath);
        }

        $verificado = (bool) $usuario->datos_bancarios_verificados_at;

        return [
            'id' => $usuario->id,
            'usuario_id' => $usuario->id,
            'banco' => $usuario->banco,
            'tipo_cuenta' => $usuario->tipo_cuenta,
            'numero_cuenta' => $numeroCuenta,
            'numero_cuenta_parcial' => $parcial,
            'titular' => $usuario->nombre,
            'es_principal' => true,
            'estado' => $verificado ? 'verificado' : 'pendiente',
            'verificado' => $verificado,
            'verificado_fecha' => $usuario->datos_bancarios_verificados_at,
            'tiene_certificado' => !empty($certificadoPath),
            'certificado_url' => $certificadoUrl,
            'created_at' => $usuario->created_at,
            'updated_at' => $usuario->updated_at,
        ];
    }

    private function formatearCedula(Usuario $usuario): array
    {
        $tieneFrente = !empty($usuario->cedula_foto_frente);
        $tieneAtras = !empty($usuario->cedula_foto_atras);

        return [
            'tiene_fotos' => $tieneFrente && $tieneAtras,
            'frente_url' => $tieneFrente ? Storage::disk('public')->url($usuario->cedula_foto_frente) : null,
            'atras_url' => $tieneAtras ? Storage::disk('public')->url($usuario->cedula_foto_atras) : null,
            'verificada' => (bool) $usuario->cedula_verificada_at,
            'fecha_verificacion' => $usuario->cedula_verificada_at,
            'pendiente' => $tieneFrente && $tieneAtras && !$usuario->cedula_verificada_at,
            'ultima_actualizacion' => $usuario->updated_at,
        ];
    }

    private function registrarDocumentoCertificado(int $usuarioId, string $path, int $size): void
    {
        $registro = DB::table('documentos')
            ->where('usuario_id', $usuarioId)
            ->where('tipo', 'certificado_bancario')
            ->first();

        $data = [
            'usuario_id' => $usuarioId,
            'tipo' => 'certificado_bancario',
            'nombre_archivo' => basename($path),
            'ruta_archivo' => $path,
            'url_publica' => Storage::disk('public')->url($path),
            'tamaño_bytes' => $size,
            'fecha_generacion' => now(),
            'updated_at' => now(),
        ];

        if ($registro) {
            DB::table('documentos')
                ->where('id', $registro->id)
                ->update($data);
        } else {
            $data['created_at'] = now();
            DB::table('documentos')->insert($data);
        }
    }
}
