<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\NotificacaoCobranca;
use App\Models\NotificacaoCobrancaConfig;
use App\Models\NotificacaoCobrancaHistorico;
use App\Services\EvolutionAPIService;
use App\Services\OnzFinanceService;
use App\Services\PayMundiService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Writer\PngWriter;

class NotificacaoCobrancaCronController extends Controller
{
    public $evolutionApiService;

    public function __construct(EvolutionAPIService $evolutionApiService)
    {
        $this->evolutionApiService = $evolutionApiService;
    }

    public function disparar()
    {
        $now = Carbon::now('America/Sao_Paulo');
        // if ($now->hour < 6 || $now->hour >= 22) {
        //     return response()->json(['message' => 'Notificações não enviadas fora do horário permitido.'], 200);
        // }
        $qtdEnviadas = 0;

        $notificacoes = NotificacaoCobranca::where('status', 1)
            ->where(function ($query) use ($now) {
                $query->whereDate('data_envio', '!=', $now->toDateString())
                    ->orWhereNull('data_envio');
            })
            ->orderBy('data_vencimento', 'asc')
            ->limit(10)
            ->get();

        foreach ($notificacoes as $notificacao) {
            $diasAntes = explode(';', $notificacao->dias_antes_vencimento);
            $diasDepois = explode(';', $notificacao->dias_apos_vencimento);
            $dataVencimento = Carbon::parse($notificacao->data_vencimento);
            $dataAtual = Carbon::now('America/Sao_Paulo');
            $dataAtualFormatada = $dataAtual->format('Y-m-d');
            $instancia = 'EMPRESA_SLYM_' . $notificacao->empresa_id;

            foreach ($diasAntes as $diaAntes) {
                $diaAntes = (int)$diaAntes;
                if ($diaAntes <= 0 || empty($diaAntes)) {
                    continue;
                }
                $dataVencimentoNew = $dataVencimento->copy()->subDays($diaAntes);

                if ($dataAtual->isSameDay($dataVencimentoNew)) {
                    if ($this->checkWhatsappConectado($instancia)) {
                        // Enviar notificação
                        if ($this->enviarMensagem($instancia, $notificacao)) {
                            $qtdEnviadas++;
                        }
                    }
                }
            }

            foreach ($diasDepois as $diaDepois) {
                $diaDepois = (int)$diaDepois;
                if ($diaDepois <= 0 || empty($diaDepois)) {
                    continue;
                }
                $dataVencimentoNew = $dataVencimento->copy()->addDays($diaDepois);

                if ($dataAtual->isSameDay($dataVencimentoNew)) {
                    if ($this->checkWhatsappConectado($instancia)) {
                        // Enviar notificação
                        if ($this->enviarMensagem($instancia, $notificacao)) {
                            $qtdEnviadas++;
                        }
                    }
                }
            }

            if ($dataAtual->isSameDay($dataVencimento)) {
                if ($notificacao->recorrente == 1) {
                    $notificacao->data_envio = $dataAtualFormatada;
                    $notificacao->data_vencimento = Carbon::parse($notificacao->data_vencimento)->addMonth();
                    $notificacao->save();
                }

                if ($this->checkWhatsappConectado($instancia)) {
                    // Enviar notificação
                    if ($this->enviarMensagem($instancia, $notificacao)) {
                        $qtdEnviadas++;
                    }
                }
            }
        }

        if ($qtdEnviadas == 0) {
            return response()->json(['message' => 'Nenhuma notificação enviada.'], 200);
        }

        return response()->json(['message' => "Notificações enviadas com sucesso: {$qtdEnviadas} notificações!"], 200);
    }

    public function checkWhatsappConectado($instancia)
    {
        $responseWpp = @$this->evolutionApiService->instanceCheck($instancia);
        return @$responseWpp['instance']['state'] == 'open';
    }

    public function enviarMensagem($instancia, $notificacao)
    {
        $notificacaoConfig = NotificacaoCobrancaConfig::where('empresa_id', $notificacao->empresa_id)->first();
        $valor = number_format($notificacao->valor, 2, ",", ".");
        $dataVencimento = Carbon::parse($notificacao->data_vencimento)->format('d/m/Y');
        $pixImagem = "";
        $pixCopiaCola = null;
        $txid = null;

        if ($notificacao->gateway == 'onz_finance') {
            $onzFinanceService = new OnzFinanceService($notificacaoConfig->id);
            $pix = $onzFinanceService->gerarPix([
                'cliente' => $notificacao->cliente,
                'valor' => $notificacao->valor,
                'cpf_cnpj' => $notificacao->cpf_cnpj,
                'titulo' => $notificacao->titulo,
            ]);

            $pixCopiaCola = $pix['pixCopiaECola'] ?? null;
            $txid = $pix['txid'] ?? null;
        } else if ($notificacao->gateway == 'pay_mundi') {
            $payMundiService = new PayMundiService($notificacaoConfig->public_key_cashin_paymundi, $notificacaoConfig->secret_key_cashin_paymundi);
            $pix = $payMundiService->gerarPix([
                'cliente' => $notificacao->cliente,
                'valor' => $notificacao->valor,
                'cpf_cnpj' => $notificacao->cpf_cnpj,
                'titulo' => $notificacao->titulo,
            ]);

            if (isset($pix['error']) && $pix['error'] == true) {
                Log::error('Erro ao gerar PIX Paymundi: ' . $pix['error']);
                return false;
            }

            $pixCopiaCola = @$pix['dataQR']['paymentCode'] ?? null;
            $txid = @$pix['trxid'] ?? null;
        }

        if ($pixCopiaCola) {
            $writer = new PngWriter();

            $qrCode = new QrCode(
                data: $pixCopiaCola,
                encoding: new Encoding('UTF-8'),
                errorCorrectionLevel: ErrorCorrectionLevel::Low,
                size: 300,
                margin: 10,
                roundBlockSizeMode: RoundBlockSizeMode::Margin,
                foregroundColor: new Color(0, 0, 0),
                backgroundColor: new Color(255, 255, 255)
            );

            $result = $writer->write($qrCode);
            $pixImagem = base64_encode($result->getString());
        }

        if ($notificacaoConfig->frase_cobranca) {
            $mensagem = str_replace(
                ['@cliente', '@dataVencimento', '@valor', '@codigoPix'],
                [$notificacao->cliente, $dataVencimento, $valor, $pixCopiaCola],
                $notificacaoConfig->frase_cobranca
            );
        } else {
            $mensagem = "Olá {$notificacao->cliente}, sua cobrança está vencida em {$dataVencimento} no valor de R$ {$valor}.";
        }

        $responseWpp = @$this->evolutionApiService->sendMessage($instancia, $mensagem, $notificacao->whatsapp);

        if ($pixImagem) {
            $this->evolutionApiService->sendMedia($instancia, $pixCopiaCola, $pixImagem, $notificacao->whatsapp, "image");
        }

        $status = !empty($responseWpp);
        if ($status) {
            $notificacao->data_envio = Carbon::now('America/Sao_Paulo')->format('Y-m-d H:i:s');
            $notificacao->save();

            NotificacaoCobrancaHistorico::create([
                'notificacao_cobranca_id' => $notificacao->id,
                'empresa_id' => $notificacao->empresa_id,
                'status' => 1,
                'pix_copia_cola' => $pixCopiaCola,
                'mensagem' => $mensagem,
                'gateway' => $notificacao->gateway,
                'externo_id' => $txid,
            ]);
        } else {
            NotificacaoCobrancaHistorico::create([
                'notificacao_cobranca_id' => $notificacao->id,
                'empresa_id' => $notificacao->empresa_id,
                'status' => 2,
                'pix_copia_cola' => $pixCopiaCola,
                'mensagem' => $mensagem,
                'gateway' => $notificacao->gateway,
                'externo_id' => $txid,
            ]);
        }

        return $status;
    }

    public function webhookOnz(Request $request)
    {
        return $this->processarWebhook($request, 'txId', 'LIQUIDATED');
    }

    public function webhookPayMundi(Request $request)
    {
        return $this->processarWebhook($request, 'trxid', 'LIQUIDATED');
    }

    private function processarWebhook(Request $request, $idKey, $statusEsperado)
    {
        $data = $request->all();

        if (empty($data['data'][$idKey])) {
            Log::warning("Webhook recebido sem $idKey.");
            return response()->json(['message' => "Campo $idKey ausente."], 400);
        }

        if (@$data['data']['status'] != $statusEsperado) {
            Log::info("Webhook ignorado. Status recebido: " . @$data['data']['status']);
            return response()->json(['message' => 'Status não corresponde ao esperado.'], 200);
        }

        $notificacaoCobrancaHist = NotificacaoCobrancaHistorico::where('externo_id', $data['data'][$idKey])
            ->where('status', 1)
            ->first();

        if (!$notificacaoCobrancaHist) {
            Log::warning("Histórico não encontrado para $idKey: " . $data['data'][$idKey]);
            return response()->json(['message' => 'Histórico não encontrado.'], 404);
        }

        $notificacaoCobranca = NotificacaoCobranca::find($notificacaoCobrancaHist->notificacao_cobranca_id);
        if ($notificacaoCobranca) {
            $notificacaoCobranca->status = 3; // Pago
            $notificacaoCobranca->save();

            NotificacaoCobrancaHistorico::create([
                'notificacao_cobranca_id' => $notificacaoCobranca->id,
                'empresa_id' => $notificacaoCobranca->empresa_id,
                'gateway' => $notificacaoCobranca->gateway,
                'externo_id' => $data['data'][$idKey],
                'status' => 3,
                'pix_copia_cola' => $notificacaoCobrancaHist->pix_copia_cola,
                'mensagem' => $notificacaoCobrancaHist->mensagem,
            ]);

            Log::info("Webhook processado com sucesso para $idKey: " . $data['data'][$idKey]);
            return response()->json(['message' => 'Webhook processado com sucesso.'], 200);
        }

        Log::error("Notificação de cobrança não encontrada para histórico: " . $notificacaoCobrancaHist->id);
        return response()->json(['message' => 'Notificação de cobrança não encontrada.'], 404);
    }
}
