<?php

namespace App\Http\Controllers\Traits;

use App\Models\Adminsettings;
use App\Models\User;
use SendGrid;
use SendGrid\Mail\Mail;
use SendGrid\Mail\Attachment;
use Illuminate\Support\Facades\Log;

trait EmailTrait
{
    /**
     * Get email settings from database
     * 
     * @return array
     */
    private function getEmailSettings()
    {
        try {
            $emailOptions = [
                'email_mail_from_address',
                'email_mail_encryption', 
                'email_api_key',
                'email_mail_from_name', 
                'email_mail_host', 
                'email_mail_port', 
                'email_mail_password'
            ];
            $admin = User::where('user_type', config('constants.user_types.admin'))->first();
            $settings = Adminsettings::where('customer_id', $admin->id)
                ->whereIn('key', $emailOptions)
                ->pluck('value', 'key')
                ->mapWithKeys(function ($value, $key) {
                    $key = $key;
                    return [$key => $value];
                })
                ->toArray();
    
            return $settings;
        } catch (\Exception $e) {
            Log::error("Failed to fetch email settings: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Send email using customer specific email configuration
     * 
     * @param array $params
     * @return bool
     */
    public function SendInstantEmail(array $params)
    {
        try {
            // Validate email address
            if (empty($params['to']) || !filter_var($params['to'], FILTER_VALIDATE_EMAIL)) {
                Log::error("Email sending failed: Invalid recipient email", [
                    'to' => $params['to'] ?? 'not provided'
                ]);
                return false;
            }
            
            // Get email settings from database
            $emailSettings = $this->getEmailSettings();
            
            // Validate sender email
            if (empty($emailSettings['email_mail_from_address']) || 
                !filter_var($emailSettings['email_mail_from_address'], FILTER_VALIDATE_EMAIL)) {
                Log::error("Email sending failed: Invalid sender email", [
                    'from' => $emailSettings['email_mail_from_address'] ?? 'not provided'
                ]);
                return false;
            }
            
            $email = new Mail();
            $email->setFrom(
                $emailSettings['email_mail_from_address'] , 
                $emailSettings['email_mail_from_name'] ?? "WMS"
            );
            $email->setSubject($params['subject']);
            $email->addTo($params['to']);
            $email->addContent("text/plain", strip_tags($params['msg'])); // Plain text version
            $email->addContent("text/html", $params['msg']); // HTML version
            
            // Handle attachments if provided
            if (!empty($params['attachments']) && is_array($params['attachments'])) {
                foreach ($params['attachments'] as $attachmentData) {
                    $filePath = null;
                    $fileName = null;
                    
                    // Check if file exists in public directory
                    if (isset($attachmentData['path']) && file_exists(public_path($attachmentData['path']))) {
                        $filePath = public_path($attachmentData['path']);
                        $fileName = $attachmentData['name'] ?? basename($attachmentData['path']);
                    } elseif (isset($attachmentData['path']) && file_exists($attachmentData['path'])) {
                        // Handle absolute paths
                        $filePath = $attachmentData['path'];
                        $fileName = $attachmentData['name'] ?? basename($filePath);
                    }
                    
                    if ($filePath && $fileName && file_exists($filePath)) {
                        try {
                            $fileContent = file_get_contents($filePath);
                            if ($fileContent === false) {
                                Log::error("Failed to read attachment file", [
                                    'path' => $filePath
                                ]);
                                continue;
                            }
                            
                            $fileEncoded = base64_encode($fileContent);
                            
                            // Create SendGrid Attachment object
                            $attachment = new Attachment();
                            $attachment->setContent($fileEncoded);
                            $attachment->setType($attachmentData['type'] ?? 'application/pdf');
                            $attachment->setFilename($fileName);
                            $attachment->setDisposition('attachment');
                            
                            $email->addAttachment($attachment);
                            
                            Log::info("Attachment added to email", [
                                'filename' => $fileName,
                                'type' => $attachmentData['type'] ?? 'application/pdf',
                                'size' => strlen($fileContent)
                            ]);
                        } catch (\Exception $e) {
                            Log::error("Failed to add attachment", [
                                'path' => $filePath,
                                'error' => $e->getMessage()
                            ]);
                        }
                    } else {
                        Log::warning("Attachment file not found", [
                            'path' => $attachmentData['path'] ?? 'not provided',
                            'name' => $fileName ?? 'not provided',
                            'filePath' => $filePath ?? 'not determined',
                            'exists' => $filePath ? (file_exists($filePath) ? 'yes' : 'no') : 'N/A'
                        ]);
                    }
                }
            }
            
            // Use API key from settings table or fall back to .env
            $password = $emailSettings['email_mail_password'] ?? null;
            if (empty($password)) {
                Log::error("Email sending failed: No API key found");
                return false;
            }
            
            $sendgrid = new SendGrid($password);
            $response = $sendgrid->send($email);

            if ($response->statusCode() >= 200 && $response->statusCode() < 300) {
                return true;
            } else {
                Log::error("SendGrid email failed. Status Code: " . $response->statusCode());
                return false;
            }
        } catch (\Exception $e) {
            Log::error("Email sending failed: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send referral signup email to user
     * 
     * @param array $userData
     * @return bool
     */
    public function sendReferralSignupUserEmail(array $userData)
    {
        try {
            $emailData = [
                'email_type' => 'referral_signup_user',
                'name' => $userData['name'] ?? 'Valued Partner',
                'email' => $userData['email'] ?? '',
                'mobile_number' => $userData['mobile_number'] ?? '',
                'applied_at' => $userData['applied_at'] ?? \Carbon\Carbon::now(),
            ];

            $params = [
                'to' => $userData['email'],
                'subject' => 'Your Referral Request is Pending Approval | ' . env('APP_NAME'),
                'msg' => view('Emails.referral-notification', $emailData)->render(),
            ];

            return $this->SendInstantEmail($params);
        } catch (\Exception $e) {
            Log::error("Referral signup user email failed: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send referral signup notification email to admin
     * 
     * @param array $userData
     * @return bool
     */
    public function sendReferralSignupAdminEmail(array $userData)
    {
        try {
            // Get all admin users
            $adminUsers = User::where('user_type', 1)->get();
            
            if ($adminUsers->isEmpty()) {
                Log::warning("No admin users found for referral signup notification");
                return false;
            }

            $emailData = [
                'email_type' => 'referral_signup_admin',
                'name' => $userData['name'] ?? 'N/A',
                'email' => $userData['email'] ?? 'N/A',
                'mobile_number' => $userData['mobile_number'] ?? 'N/A',
                'applied_at' => $userData['applied_at'] ?? \Carbon\Carbon::now(),
            ];

            $successCount = 0;
            foreach ($adminUsers as $admin) {
                $params = [
                    'to' => $admin->email,
                    'subject' => 'New Referral Signup Request | ' . env('APP_NAME'),
                    'msg' => view('Emails.referral-notification', $emailData)->render(),
                ];

                if ($this->SendInstantEmail($params)) {
                    $successCount++;
                }
            }

            return $successCount > 0;
        } catch (\Exception $e) {
            Log::error("Referral signup admin email failed: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send referral approval email to user
     * 
     * @param array $userData
     * @return bool
     */
    public function sendReferralApprovalEmail(array $userData)
    {
        try {
            $emailData = [
                'email_type' => 'referral_approved',
                'name' => $userData['name'] ?? 'Valued Partner',
                'email' => $userData['email'] ?? '',
                'referral_code' => $userData['referral_code'] ?? '',
                'referral_link' => $userData['referral_link'] ?? '',
                'approved_at' => $userData['approved_at'] ?? \Carbon\Carbon::now(),
            ];

            $params = [
                'to' => $userData['email'],
                'subject' => 'Referral Partnership Approved! | ' . env('APP_NAME'),
                'msg' => view('Emails.referral-notification', $emailData)->render(),
            ];

            return $this->SendInstantEmail($params);
        } catch (\Exception $e) {
            Log::error("Referral approval email failed: " . $e->getMessage());
            return false;
        }
    }
}