<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\ClinicIdentity;
use App\Models\MedicalService;
use App\Models\Patients;
use App\Models\Especiality;
use App\Models\User;
use App\Models\Appointments;
use App\Helper\Helper;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;
use App\Models\Service;
use App\Mail\AppointmentMailWithTemplate;
use App\Models\Settings;
use DateTime;
use DateTimeZone;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactFormMail;
use App\Exceptions\GlobalException;
use App\Http\Controllers\AppointmentController;

class PortalController extends Controller
{
    /**
     * Muestra la página de inicio del portal
     */
    public function index()
    {
        $clinicIdentity = ClinicIdentity::getActive();
        $featuredServices = MedicalService::where('is_active', true)
            ->orderBy('created_at', 'desc')
            ->take(3)
            ->get();
        
        return view('portal.index', [
            'clinicIdentity' => $clinicIdentity,
            'featuredServices' => $featuredServices
        ]);
    }

    /**
     * Muestra la página de servicios
     */
    public function services()
    {
        $clinicIdentity = ClinicIdentity::getActive();
        $services = MedicalService::where('is_active', true)->get();
        
        return view('portal.services', [
            'clinicIdentity' => $clinicIdentity,
            'services' => $services
        ]);
    }

    /**
     * Muestra la página de contacto
     */
    public function contact()
    {
        $page_title = "Contacto";
        $clinicIdentity = ClinicIdentity::first();
        return view('portal.contact', compact('page_title', 'clinicIdentity'));
    }

    public function submitContact(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255',
            'subject' => 'required|string|max:255',
            'message' => 'required|string',
        ]);

        // Enviar correo electrónico a la clínica
        $clinicIdentity = ClinicIdentity::first();
        $clinicEmail = $clinicIdentity->email ?? 'info@medicalcenter.com';

        Mail::to($clinicEmail)->send(new ContactFormMail($request->all()));

        // Redireccionar con mensaje de éxito
        return redirect()->route('portal.contact')->with('success', 'Su mensaje ha sido enviado correctamente. Nos pondremos en contacto pronto.');
    }

    /**
     * Muestra el formulario de registro de pacientes
     */
    public function register()
    {
        $clinicIdentity = ClinicIdentity::getActive();
        
        return view('portal.register', [
            'clinicIdentity' => $clinicIdentity
        ]);
    }

    /**
     * Guarda un nuevo paciente
     */
    public function storePatient(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'identification' => 'required|string|max:20',
            'birthday' => 'required|date_format:d/m/Y',
            'age' => 'required|numeric',
            'gender' => 'required|in:M,F',
            'phone' => 'required|string|max:20',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string|max:255',
            'blood_type' => 'nullable|string|max:10'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $data = $request->all();
        $patientId = Helper::createId();
        
        $patient = new Patients();
        $patient->id = $patientId;
        $patient->identification = $data['identification'];
        $patient->firstname = $data['firstname'];
        $patient->lastname = $data['lastname'];
        $patient->birthday = date_create_from_format('d/m/Y', $data['birthday']);
        $patient->age = $data['age'];
        $patient->gender = $data['gender'];
        $patient->phone = $data['phone'];
        $patient->email = $data['email'] ?? null;
        $patient->address = $data['address'] ?? null;
        $patient->blood_type = $data['blood_type'] ?? null;
        $patient->save();

        return redirect()->route('portal.appointments')
            ->with('success', 'Registro exitoso. Ahora puedes agendar tu cita.');
    }

    /**
     * Muestra el formulario para agendar citas
     */
    public function appointments()
    {
        $clinicIdentity = ClinicIdentity::getActive();
        $especialities = Especiality::getEspecialities();
        $doctors = User::whereHas('roles', function($q) {
            $q->where('name', 'doctor');
        })->get();
        
        return view('portal.appointments', [
            'clinicIdentity' => $clinicIdentity,
            'especialities' => $especialities,
            'doctors' => $doctors
        ]);
    }

    /**
     * Guarda una nueva cita
     */
    public function storeAppointment(Request $request)
    {
       try {
        $validator = Validator::make($request->all(), [
            'patientIdentificationNumber' => 'required|string',
            'especiality' => 'required|string',
            'users_id' => 'required|string',
            'time' => 'required|string',
            'summary' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $data = $request->all();
        
        // Buscar paciente por identificación
        $patient = Patients::where('identification', $data['patientIdentificationNumber'])->first();
        
        if (!$patient) {
            return redirect()->back()
                ->with('error', 'Paciente no encontrado. Regístrese primero.')
                ->withInput();
        }

        // Crear la cita
        $appointment = new Appointments();
        $appointment->id = Helper::createId();
        $appointment->patients_id = $patient->id;
        $appointment->especiality = $data['especiality'];
        $appointment->users_id = $data['users_id'];
        try {
            // Usar createFromFormat en lugar de parse para asegurar el formato correcto
            $appointment->date = Carbon::createFromFormat('d/m/Y H:i:s', $data['time']);
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Formato de fecha incorrecto. Por favor, intente de nuevo.')
                ->withInput();
        }
        $appointment->summary = $data['summary'] ?? 'Cita programada desde el portal';
        $appointment->code = "MED-" . Appointments::count() + 1;
        $appointment->active = 1;
        $appointment->deleted = 0;
        if(AppointmentController::validateThereAppointment($appointment->date,$appointment->users_id)){
            return redirect()->back()
                ->with('error', 'Ups, se te adelantaron, esta hora ya está ocupada, intenta crear de nuevo la cita')
                ->withInput();
        }
        $appointment->save();

        // Enviar correo electrónico de confirmación
        $this->sendAppointmentEmail($appointment);

        return redirect()->route('portal.appointments')
            ->with('success', 'Cita agendada exitosamente. Te esperamos.');    
       } catch (\Throwable $th) {
           return redirect()->back()
                ->with('error', 'Debido a que muchos pacientes se han agendado estamos presentando pequeños retrasos, intenta agendar de nuevo ahora mismo por favor.')
                ->withInput();
       }
    }

    /**
     * Envía un correo electrónico con los detalles de la cita
     */
    private function sendAppointmentEmail($model)
    {
        $patient = $model->patient()->first();
        $date = new DateTime($model->date, new DateTimeZone(Settings::findConfigValue("TIME_ZONE") ?? 'UTC'));
        
        $dataToSend = [
            'hour' => $date->format('g:i A'),
            'date' => $date->format('d-m-Y'),
            'fullname' => $patient->firstname . " " . $patient->lastname,
            'contactNumber' => Settings::findConfigValue("CONTACT_PHONE_NUMBER") ?? '',
            'contactEmail' => Settings::findConfigValue("CONTACT_EMAIL") ?? '',
        ];

        $emails = [];
        if ($patient->age > 17) {
            if (isset($patient->email) && !empty($patient->email)) {
                array_push($emails, $patient->email);
            }
        } else {
            $emails = array_merge($emails, Patients::getEmailForRepresentatives($patient));
        }

        if (!empty($emails)) {
            $this->dispatchEmailAppointmentWithTemplate($dataToSend, $emails, $model);
        }
    }

    /**
     * Envía el correo electrónico utilizando la plantilla
     */
    private function dispatchEmailAppointmentWithTemplate($data, $emails, $appointmentModel)
    {
        Helper::sendWhatsAppMessage($appointmentModel);
        return Helper::sendEmail(
            Helper::MAIL_TO_SEND,
            $emails,
            Helper::SUBJECT_DEFAULT_MAIL_TO_SEND,
            $data,
            AppointmentMailWithTemplate::class,
            $appointmentModel
        );
    }
} 