<?php

namespace App\Http\Controllers\admin;

use App\Http\Controllers\Controller;
use App\Services\ProcesoService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class procesoController extends Controller
{
    protected $procesoService;

    public function __construct(ProcesoService $procesoService)
    {
        $this->procesoService = $procesoService;
    }
    public function updateMembershipSales(Request $request)
    {
        $lock = $this->acquireProcessLock('updateMembershipSales');
        if ($lock === null) {
            return response()->json([
                'message' => 'El proceso ya se encuentra en ejecución. Intente nuevamente en unos minutos.',
            ], 429);
        }

        try {
            $stats = $this->procesoService->updateMembershipSales();
            return response()->json([
                'message' => 'Proceso de actualización de ventas de membresías ejecutado correctamente.',
                'stats' => $stats,
            ]);
        } catch (Throwable $exception) {
            return response()->json(['message' => 'Error al ejecutar el proceso de actualización de ventas de membresías.', 'error' => $exception->getMessage()], 500);
        } finally {
            $this->releaseProcessLock($lock);
            $this->disconnectDatabaseConnections();
        }
    }
    public function updateMembershipSalesOnedays(Request $request)
    {
        $lock = $this->acquireProcessLock('updateMembershipSalesOnedays');
        if ($lock === null) {
            return response()->json([
                'message' => 'El proceso ya se encuentra en ejecución. Intente nuevamente en unos minutos.',
            ], 429);
        }

        try {
            $stats = $this->procesoService->updateMembershipSalesOnedays();
            return response()->json([
                'message' => 'Proceso de actualización de ventas de membresías ejecutado correctamente.',
                'stats' => $stats,
            ]);
        } catch (Throwable $exception) {
            return response()->json(['message' => 'Error al ejecutar el proceso de actualización de ventas de membresías.', 'error' => $exception->getMessage()], 500);
        } finally {
            $this->releaseProcessLock($lock);
            $this->disconnectDatabaseConnections();
        }
    }

    private function acquireProcessLock(string $processName): mixed
    {
        $lockDir = storage_path('framework/locks');
        if (! is_dir($lockDir)) {
            @mkdir($lockDir, 0775, true);
        }

        $lockFile = $lockDir . DIRECTORY_SEPARATOR . 'cron_' . $processName . '.lock';
        $handle = @fopen($lockFile, 'c+');
        if ($handle === false) {
            return null;
        }

        if (! @flock($handle, LOCK_EX | LOCK_NB)) {
            @fclose($handle);
            return null;
        }

        @ftruncate($handle, 0);
        @fwrite($handle, (string) getmypid());

        return $handle;
    }

    private function releaseProcessLock(mixed $handle): void
    {
        if (! is_resource($handle)) {
            return;
        }

        @flock($handle, LOCK_UN);
        @fclose($handle);
    }

    private function disconnectDatabaseConnections(): void
    {
        DB::disconnect();
        DB::disconnect('mysql');
    }
}
