<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Helper\Helper;
use Illuminate\Support\Facades\Mail;
use App\Mail\AppointmentNotificationMail;
use App\Mail\AppointmentMail;
use App\Mail\AppointmentMailWithTemplate;
use App\Http\Response\Response;
use App\Models\Representative;
use App\Models\Patients;
use App\Models\Settings;
use App\Models\RelationShip;
use App\Models\Appointments;
use App\Models\Especiality;
use Illuminate\Support\Facades\DB;
use \Acaronlex\LaravelCalendar\Calendar;
use Throwable;
use App\Exceptions\GlobalException;
use Illuminate\Support\Carbon;
use App\Models\UserProfile;
use \DateTime;
use \DateTimeZone;
use App\Models\User;
use App\Models\RoleUser;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;



class AppointmentController extends Controller
{



    /**
     * @Route("/api/appointments", name="api.appointments.create", methods={"POST"})
     */
    public function apiCreate(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'date' => 'required|date_format:d/m/Y h:i:s A',
                'patients_id' => 'required|exists:patients,id',
                'especiality' => 'required|exists:especiality,id',
                'doctorname' => 'required|exists:users,id',
                'summary' => 'required|string'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'errors' => $validator->errors()
                ], 422);
            }

            $model = new Appointments();
            
            // Convertir fecha al formato correcto
            $date = Carbon::createFromFormat('d/m/Y h:i:s A', $request->date);
            
            // Verificar conflictos de horario
            $startRange = $date->copy()->subMinutes(59);
            $endRange = $date->copy()->addMinutes(59);

            $existingAppointments = Appointments::whereBetween('date', [$startRange, $endRange])
                ->where('users_id', $request->doctorname)
                ->count();

            if ($existingAppointments > 0) {
                return response()->json([
                    'success' => false,
                    'message' => __('error-500.appointmentBusy')
                ], 409);
            }


            $data = $model->createModelFromRequest($request->all());

            try {
                $model = $model->create($data);
            } catch (\Exception $e) {
                return response()->json([
                    'success' => false,
                    'message' => 'Error creating appointment',
                    'error' => $e->getMessage()
                ], 500);
            }

            // Enviar email async con manejo de errores interno
            dispatch(function () use ($model) {
                try {
                    $this->sendAppointmentEmail($model);
                } catch (\Throwable $th) {
                    Log::error('Error sending appointment email', [
                        'appointment_id' => $model->id,
                        'error' => $th->getMessage(),
                        'trace' => $th->getTraceAsString()
                    ]);
                }
            });
            $patient = $model->patient()->first();
            return response()->json([
                'success' => true,
                'data' => [
                    'id' => $model->id,
                    'date' => $model->date,
                    'patient_id' => $model->patient()->first()->id,
                    'identification' => $model->patient()->first()->identification,
                    'patient' => $model->patient()->first()->firstname . " " .  $model->patient()->first()->lastname,
                    'doctor_id' => $model->users_id,
                    'especiality' => $model->especiality,
                    'summary' => $model->summary
                ]
            ], 201);

        } catch (\Throwable $th) {
            return response()->json([
                'success' => false,
                'message' => 'Server error',
                'error' => $th->getMessage()
            ], 500);
        }
    }

    private function sendAppointmentEmail($model){
        $patient = $model->patient()->first();
        $date = new DateTime($model->date, new DateTimeZone(Settings::findConfigValue("TIME_ZONE")));
        
        $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 ($patient->email) {
                $emails[] = $patient->email;
            }
        } else {
            $emails = array_merge($emails, Patients::getEmailForRepresentatives($patient));
        }

        // Implementar lógica de envío de email aquí
        $this->dispatchEmailAppointmentWithTemplate($dataToSend, $emails, $model);
    }

      /**
     * 
     */
    private function dispatchEmailAppointmentWithTemplate($data,$emails,$appointmentModel){
        return Helper::sendEmail(
            Helper::MAIL_TO_SEND,
            $emails,
            Helper::SUBJECT_DEFAULT_MAIL_TO_SEND,
            $data,
            AppointmentMailWithTemplate::class,
            $appointmentModel); 
    }

     /**
     * 
     */
    public function getToken(){
        $token = csrf_token();
        return Response::getResponseToken($token,200);
    }
}