<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Twilio\Rest\Client;

class NotificationService
{
    private $twilioSid;
    private $twilioToken;
    private $twilioFrom;
    private $enabled;

    public function __construct()
    {
        $this->twilioSid = env('TWILIO_SID');
        $this->twilioToken = env('TWILIO_TOKEN');
        $this->twilioFrom = env('TWILIO_WHATSAPP_FROM', 'whatsapp:+14155238886');
        $this->enabled = !empty($this->twilioSid) && !empty($this->twilioToken);
    }

    public function sendAttendanceNotification(int $studentId, string $type)
    {
        // Get student and parent info
        $student = DB::table('students')
            ->leftJoin('grades', 'students.grade_id', '=', 'grades.id')
            ->leftJoin('parent_contacts', 'students.parent_contact_id', '=', 'parent_contacts.id')
            ->select(
                'students.first_name', 'students.last_name',
                'grades.name as grade_name',
                'parent_contacts.full_name as parent_name',
                'parent_contacts.whatsapp_number'
            )
            ->where('students.id', $studentId)
            ->first();

        if (!$student || !$student->whatsapp_number) {
            Log::warning("No student or WhatsApp number found for student ID: $studentId");
            return false;
        }

        // Get message template
        $template = DB::table('message_templates')
            ->where('type', $type)
            ->where('status', 'active')
            ->first();

        if (!$template) {
            Log::warning("No active template found for type: $type");
            return false;
        }

        // Get settings for placeholders
        $settings = $this->getSettings();
        $now = now()->setTimezone($settings['timezone'] ?? 'Africa/Lagos');

        // Replace placeholders
        $message = $this->replacePlaceholders($template->content, [
            'student_name' => $student->first_name . ' ' . $student->last_name,
            'grade' => $student->grade_name,
            'parent_name' => $student->parent_name,
            'school_name' => $settings['school_name'] ?? 'Chalcedony Prime School',
            'date' => $now->format($settings['date_format'] ?? 'Y-m-d'),
            'time' => $now->format($settings['time_format'] ?? 'H:i'),
            'datetime' => $now->format(($settings['date_format'] ?? 'Y-m-d') . ' ' . ($settings['time_format'] ?? 'H:i')),
        ]);

        // Ensure WhatsApp format
        $to = $student->whatsapp_number;
        if (!str_starts_with($to, 'whatsapp:')) {
            $to = 'whatsapp:' . $to;
        }

        // Create message record
        $messageId = DB::table('messages')->insertGetId([
            'direction' => 'outbound',
            'channel' => 'whatsapp',
            'to_number' => $to,
            'status' => 'queued',
            'student_id' => $studentId,
            'payload' => json_encode([
                'template_type' => $type,
                'message' => $message,
                'to' => $to,
                'from' => $this->twilioFrom,
            ]),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        // Send if enabled
        if ($this->enabled) {
            try {
                $twilio = new Client($this->twilioSid, $this->twilioToken);
                $twilioMessage = $twilio->messages->create($to, [
                    'from' => $this->twilioFrom,
                    'body' => $message,
                ]);

                // Update with Twilio SID and status
                DB::table('messages')->where('id', $messageId)->update([
                    'twilio_sid' => $twilioMessage->sid,
                    'status' => $twilioMessage->status,
                    'updated_at' => now(),
                ]);

                Log::info("WhatsApp message sent", [
                    'student_id' => $studentId,
                    'type' => $type,
                    'twilio_sid' => $twilioMessage->sid,
                ]);

                return true;
            } catch (\Exception $e) {
                // Update status to failed
                DB::table('messages')->where('id', $messageId)->update([
                    'status' => 'failed',
                    'payload' => json_encode(array_merge(
                        json_decode(DB::table('messages')->where('id', $messageId)->value('payload'), true),
                        ['error' => $e->getMessage()]
                    )),
                    'updated_at' => now(),
                ]);

                Log::error("Failed to send WhatsApp message", [
                    'student_id' => $studentId,
                    'type' => $type,
                    'error' => $e->getMessage(),
                ]);

                return false;
            }
        } else {
            // Update status to indicate not sent (no credentials)
            DB::table('messages')->where('id', $messageId)->update([
                'status' => 'not_sent_no_credentials',
                'updated_at' => now(),
            ]);

            Log::info("WhatsApp message queued but not sent (no Twilio credentials)", [
                'student_id' => $studentId,
                'type' => $type,
                'message_id' => $messageId,
            ]);

            return true; // Consider it successful for logging purposes
        }
    }

    private function getSettings(): array
    {
        $rows = DB::table('settings')->select('key', 'value')->get();
        $settings = [];
        foreach ($rows as $row) {
            $settings[$row->key] = $row->value;
        }
        return $settings;
    }

    private function replacePlaceholders(string $template, array $values): string
    {
        foreach ($values as $key => $value) {
            $template = str_replace("{{$key}}", $value, $template);
        }
        return $template;
    }

    public function sendTestMessage(string $toNumber, string $message): bool
    {
        // Normalize destination
        $to = $toNumber;
        if (!str_starts_with($to, 'whatsapp:')) {
            $to = 'whatsapp:' . $to;
        }

        // Create message record
        $messageId = DB::table('messages')->insertGetId([
            'direction' => 'outbound',
            'channel' => 'whatsapp',
            'to_number' => $to,
            'status' => 'queued',
            'student_id' => null,
            'payload' => json_encode([
                'template_type' => 'test',
                'message' => $message,
                'to' => $to,
                'from' => $this->twilioFrom,
            ]),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        if ($this->enabled) {
            try {
                $twilio = new Client($this->twilioSid, $this->twilioToken);
                $twilioMessage = $twilio->messages->create($to, [
                    'from' => $this->twilioFrom,
                    'body' => $message,
                ]);
                DB::table('messages')->where('id', $messageId)->update([
                    'twilio_sid' => $twilioMessage->sid,
                    'status' => $twilioMessage->status,
                    'updated_at' => now(),
                ]);
                return true;
            } catch (\Exception $e) {
                DB::table('messages')->where('id', $messageId)->update([
                    'status' => 'failed',
                    'payload' => json_encode(array_merge(
                        json_decode(DB::table('messages')->where('id', $messageId)->value('payload'), true),
                        ['error' => $e->getMessage()]
                    )),
                    'updated_at' => now(),
                ]);
                return false;
            }
        } else {
            DB::table('messages')->where('id', $messageId)->update([
                'status' => 'not_sent_no_credentials',
                'updated_at' => now(),
            ]);
            return true;
        }
    }
}
