<?php

namespace App\Http\Controllers;

use App\Models\ConfigCorreo;
use App\Helpers\CorreoHelper;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

class ConfigCorreoController extends Controller
{
    /**
     * Obtener todas las configuraciones de correo
     */
    public function index(): JsonResponse
    {
        $configuraciones = ConfigCorreo::orderBy('es_activa', 'desc')
            ->orderBy('nombre')
            ->get();

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

    /**
     * Obtener una configuración específica
     */
    public function show($id): JsonResponse
    {
        $configuracion = ConfigCorreo::find($id);

        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

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

    /**
     * Obtener la configuración activa
     */
    public function getActiva(): JsonResponse
    {
        $configuracion = ConfigCorreo::getConfigActiva();

        if (!$configuracion) {
            // Si no hay configuración activa, usar la predeterminada
            $configuracion = ConfigCorreo::getConfigPredeterminada();
        }

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

    /**
     * Crear una nueva configuración
     */
    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'nombre' => 'required|string|max:100',
            'correo_prueba' => 'required|email|max:255',
            'modo_prueba' => 'boolean',
            'es_activa' => 'boolean',
        ]);

        $configuracion = ConfigCorreo::create($request->all());

        // Si se marca como activa, desactivar las demás
        if ($configuracion->es_activa) {
            $configuracion->activar();
        }

        // Si se marca como predeterminada, quitar predeterminada a las demás
        if ($configuracion->es_predeterminada) {
            $configuracion->establecerPredeterminada();
        }

        return response()->json([
            'success' => true,
            'message' => 'Configuración creada exitosamente',
            'data' => $configuracion
        ], 201);
    }

    /**
     * Actualizar una configuración existente
     */
    public function update(Request $request, $id): JsonResponse
    {
        $configuracion = ConfigCorreo::find($id);
        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

        $request->validate([
            'nombre' => 'sometimes|required|string|max:100',
            'correo_prueba' => 'sometimes|required|email|max:255',
            'modo_prueba' => 'sometimes|boolean',
            'es_activa' => 'sometimes|boolean',
        ]);
        
        // Manejar flags especiales por separado para evitar desactivaciones accidentales
        $data = $request->all();
        $esActiva = array_key_exists('es_activa', $data) ? (bool)$data['es_activa'] : null;
        $esPredeterminada = array_key_exists('es_predeterminada', $data) ? (bool)$data['es_predeterminada'] : null;

        // Quitar flags del update normal
        unset($data['es_activa'], $data['es_predeterminada']);

        // Actualizar solo campos no especiales
        $configuracion->update($data);

        // Actualizar es_activa si fue enviado explícitamente
        if (!is_null($esActiva)) {
            if ($esActiva) {
                // Activa esta y desactiva las demás
                $configuracion->activar();
            } else {
                // Solo desactivar esta
                $configuracion->update(['es_activa' => false]);
            }
        }

        // Actualizar es_predeterminada si fue enviado explícitamente
        if (!is_null($esPredeterminada)) {
            if ($esPredeterminada) {
                // Establecer como predeterminada y quitar a las demás
                $configuracion->establecerPredeterminada();
            } else {
                // Quitar predeterminada de esta
                $configuracion->update(['es_predeterminada' => false]);
            }
        }

        return response()->json([
            'success' => true,
            'message' => 'Configuración actualizada exitosamente',
            'data' => $configuracion
        ]);
    }

    /**
     * Eliminar una configuración
     */
    public function destroy($id): JsonResponse
    {
        $configuracion = ConfigCorreo::find($id);

        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

        // No permitir eliminar la configuración predeterminada
        if ($configuracion->es_predeterminada) {
            return response()->json([
                'success' => false,
                'message' => 'No se puede eliminar la configuración predeterminada'
            ], 400);
        }

        $configuracion->delete();

        return response()->json([
            'success' => true,
            'message' => 'Configuración eliminada exitosamente'
        ]);
    }

    /**
     * Activar una configuración
     */
    public function activar($id): JsonResponse
    {
        $configuracion = ConfigCorreo::find($id);

        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

        $configuracion->activar();

        return response()->json([
            'success' => true,
            'message' => 'Configuración activada exitosamente',
            'data' => $configuracion
        ]);
    }

    /**
     * Activar/Desactivar modo prueba
     */
    public function toggleModoPrueba($id): JsonResponse
    {
        $configuracion = ConfigCorreo::find($id);

        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

        $configuracion->modo_prueba = !$configuracion->modo_prueba;
        $configuracion->save();

        return response()->json([
            'success' => true,
            'message' => $configuracion->modo_prueba ? 'Modo prueba activado' : 'Modo prueba desactivado',
            'data' => $configuracion
        ]);
    }


    /**
     * Obtener el estado del modo prueba
     */
    public function getModoPrueba(): JsonResponse
    {
        $modoPrueba = ConfigCorreo::modoPruebaActivo();
        $correoPrueba = ConfigCorreo::getCorreoPrueba();

        return response()->json([
            'success' => true,
            'data' => [
                'modo_prueba_activo' => $modoPrueba,
                'correo_prueba' => $correoPrueba
            ]
        ]);
    }

    /**
     * Enviar correo de prueba usando la configuración activa
     */
    public function enviarPrueba(Request $request): JsonResponse
    {
        try {
            // Obtener la configuración activa
            $configuracion = ConfigCorreo::getConfiguracionActiva();

            if (!$configuracion) {
                return response()->json([
                    'success' => false,
                    'message' => 'No hay una configuración de correo activa. Por favor, active una configuración primero.'
                ], 400);
            }

            // Obtener el correo de destino según la configuración
            $correoDestino = CorreoHelper::getCorreoDestino($configuracion->correo_prueba);

            if (!$correoDestino) {
                return response()->json([
                    'success' => false,
                    'message' => 'No se ha configurado un correo de prueba. Por favor, configure un correo de prueba primero.'
                ], 400);
            }

            // Enviar el correo de prueba
            Mail::send('mails.prueba_correo', ['configuracion' => $configuracion], function ($message) use ($correoDestino, $configuracion) {
                $message->to($correoDestino)
                       ->subject('EGURROLA - Correo de Prueba - ' . $configuracion->nombre);
            });

            return response()->json([
                'success' => true,
                'message' => 'Correo de prueba enviado exitosamente',
                'data' => [
                    'correo_destino' => $correoDestino,
                    'configuracion' => $configuracion->nombre,
                    'modo_prueba' => $configuracion->modo_prueba
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al enviar el correo de prueba',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Enviar ejemplo de template de correo
     */
    public function enviarEjemploTemplate(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'template' => 'required|string|in:aviso_nuevo_venta_confirmacion_cliente,aviso_nuevo_venta_cliente,aviso_nuevo_venta_admin,aviso_nuevo_cliente,aviso_nueva_cita,aviso_cambio_pw,aviso_activacion_cliente,aviso_activacion_cita,auto_aviso_nuevo_cliente,auto_aviso_nuevo_cliente_local'
            ]);

            // Obtener la configuración activa
            $configuracion = ConfigCorreo::getConfiguracionActiva();

            if (!$configuracion) {
                return response()->json([
                    'success' => false,
                    'message' => 'No hay una configuración de correo activa. Por favor, active una configuración primero.'
                ], 400);
            }

            // Obtener el correo de destino según la configuración
            $correoDestino = CorreoHelper::getCorreoDestino($configuracion->correo_prueba);

            if (!$correoDestino) {
                return response()->json([
                    'success' => false,
                    'message' => 'No se ha configurado un correo de prueba. Por favor, configure un correo de prueba primero.'
                ], 400);
            }

            $template = $request->input('template');
            $view = 'mails.' . $template;
            $data = $this->generarDatosEjemplo($template);
            $subject = $this->obtenerAsuntoTemplate($template);

            // Enviar el correo de ejemplo
            Mail::send($view, $data, function ($message) use ($correoDestino, $subject) {
                $message->to($correoDestino)
                       ->subject('EGURROLA - Ejemplo: ' . $subject);
            });

            return response()->json([
                'success' => true,
                'message' => 'Correo de ejemplo enviado exitosamente',
                'data' => [
                    'template' => $template,
                    'correo_destino' => $correoDestino,
                    'subject' => $subject
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al enviar el correo de ejemplo',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Generar datos de ejemplo para los templates
     */
    private function generarDatosEjemplo(string $template): array
    {
        $now = now();
        
        // Crear datos de ejemplo comunes
        $clienteEjemplo = (object)[
            'id' => 1,
            'razonSocial' => 'Cliente de Ejemplo S.A. de C.V.',
            'email' => 'cliente@ejemplo.com',
            'celular' => '5551234567',
        ];

        $userEjemplo = (object)[
            'id' => 1,
            'name' => 'Juan Pérez',
            'email' => 'usuario@ejemplo.com',
            'uuid' => '123e4567-e89b-12d3-a456-426614174000',
            'created_at' => $now->copy()->subDays(2),
            'updated_at' => $now,
            'tipo_cliente' => 'cliente_linea'
        ];

        $sucursalEjemplo = (object)[
            'id' => 1,
            'nombre' => 'Sucursal Centro'
        ];

        $ventaEjemplo = (object)[
            'id' => 1,
            'total' => 1500.00,
            'fecha' => $now->copy()->subDay(), // Alias para fecha_registro
            'fecha_registro' => $now->copy()->subDay(),
            'created_at' => $now->copy()->subDay(),
            'status' => 'pendiente',
            'estatus' => 'pendiente',
            'cliente' => $clienteEjemplo,
        ];

        $sesionEjemplo = (object)[
            'id' => 100,
            'fecha_asignada' => $now->copy()->addDays(3),
            'cliente' => $clienteEjemplo,
            'sucursal' => $sucursalEjemplo,
            'terapista' => (object)[
                'id' => 1,
                'name' => 'María González'
            ]
        ];

        // Asignar user al cliente para templates que lo necesitan
        $clienteEjemplo->user = $userEjemplo;

        // Retornar datos según el template
        switch ($template) {
            case 'aviso_nuevo_venta_confirmacion_cliente':
            case 'aviso_nuevo_venta_cliente':
            case 'aviso_nuevo_venta_admin':
                return ['venta' => $ventaEjemplo];

            case 'aviso_nuevo_cliente':
                return ['user' => $userEjemplo];

            case 'aviso_nueva_cita':
            case 'aviso_activacion_cita':
                return ['sesion' => $sesionEjemplo];

            case 'aviso_cambio_pw':
                return ['user' => $userEjemplo];

            case 'aviso_activacion_cliente':
                return ['user' => $userEjemplo];

            case 'auto_aviso_nuevo_cliente':
            case 'auto_aviso_nuevo_cliente_local':
                return ['user' => $userEjemplo];

            default:
                return [];
        }
    }

    /**
     * Obtener el asunto del template
     */
    private function obtenerAsuntoTemplate(string $template): string
    {
        $asuntos = [
            'aviso_nuevo_venta_confirmacion_cliente' => 'Venta Confirmada',
            'aviso_nuevo_venta_cliente' => 'Nueva Venta',
            'aviso_nuevo_venta_admin' => 'Nueva Venta (Admin)',
            'aviso_nuevo_cliente' => 'Nuevo Cliente Registrado',
            'aviso_nueva_cita' => 'Nueva Solicitud de Cita',
            'aviso_cambio_pw' => 'Restablecimiento de Contraseña',
            'aviso_activacion_cliente' => 'Cuenta Activada',
            'aviso_activacion_cita' => 'Cita Autorizada',
            'auto_aviso_nuevo_cliente' => 'Registro Completado',
            'auto_aviso_nuevo_cliente_local' => 'Registro Completado (Activo)',
        ];

        return $asuntos[$template] ?? 'Template de Correo';
    }

    /**
     * Obtener la URL del logo de la empresa
     */
    public function getLogoUrl(): JsonResponse
    {
        try {
            $logoUrl = CorreoHelper::getLogoUrl();
            
            return response()->json([
                'success' => true,
                'data' => [
                    'logo_url' => $logoUrl,
                    'logo_path' => str_replace(url('/'), '', $logoUrl)
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener la URL del logo',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Obtener impresoras del servicio externo
     */
    public function obtenerImpresoras(): JsonResponse
    {
        try {
            // Realizar petición GET al endpoint externo
            $response = Http::timeout(10)->get('http://localhost:8080/printers');

            // Obtener el código de estado HTTP
            $statusCode = $response->status();

            // Obtener el cuerpo de la respuesta
            $body = $response->body();
            
            // Intentar decodificar como JSON, si no, devolver como texto
            $data = null;
            try {
                $data = $response->json();
            } catch (\Exception $e) {
                $data = $body;
            }

            return response()->json([
                'success' => $statusCode >= 200 && $statusCode < 300,
                'status_code' => $statusCode,
                'data' => $data,
                'raw_response' => $body,
                'headers' => $response->headers()
            ], $statusCode >= 200 && $statusCode < 300 ? 200 : $statusCode);

        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            return response()->json([
                'success' => false,
                'message' => 'No se pudo conectar al servicio de impresoras',
                'error' => $e->getMessage(),
                'details' => 'El servicio en localhost:8080 no está disponible o no responde'
            ], 503);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener las impresoras',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
