<?php

namespace App\Models;

use Illuminate\Support\Facades\Date;
use App\ColorPicker;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Validator;

class PremiumEmail extends Model
{
    use ColorPicker;
    use HasFactory;

    protected $fillable = [
        'user_id',
        'message_id',
        'subject',
        'from_name',
        'from_email',
        'to',
        'cc',
        'bcc',
        'timestamp',
        'body_text',
        'body_html',
        'is_seen',
        'is_flagged',
        'size',
        'mailbox',
        'raw_headers',
        'raw_body',
        'attachments',
    ];

    protected $casts = [
        'to' => 'array',
        'cc' => 'array',
        'bcc' => 'array',
        'attachments' => 'array',
        'timestamp' => 'datetime',
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public static function createEmail(array $message, $email): void
    {
        $initialData = $message;
        if (config('app.fetch_from_db') && config('app.fetch_from_remote_db')) {
            $utcTime = CarbonImmutable::parse($message['timestamp'])->setTimezone('UTC')->toDateTimeString();
        } else {
            $utcTime = CarbonImmutable::instance($message['timestamp'])->setTimezone('UTC')->toDateTimeString();
        }
        $messageId = Date::parse($utcTime)->format('Ymd').$initialData['id'];
        $userId = \auth()->user()->id;
        $exists = PremiumEmail::query()->where('user_id', $userId)->where('message_id', $messageId)->exists();

        $data = [
            'user_id' => $userId,
            'message_id' => $messageId,
            'subject' => $initialData['subject'],
            'from_name' => $initialData['sender_name'],
            'from_email' => $initialData['sender_email'],
            'to' => ["$email"],
            'cc' => [],
            'bcc' => [],
            'timestamp' => $utcTime,
            'body_text' => $initialData['contentText'],
            'body_html' => $initialData['content'],
            'is_seen' => true,
            'is_flagged' => false,
            'size' => $initialData['size'] ?? 0,
            'mailbox' => 'INBOX',
            'raw_headers' => null,
            'raw_body' => null,
            'attachments' => $initialData['attachments'],
        ];

        if (! $exists) {
            PremiumEmail::query()->create($data);
        }
    }

    public static function fetchEmailFromDB($userId)
    {

        $validator = Validator::make(['user_id' => $userId], [
            'user_id' => ['required', 'integer'],
        ]);

        if ($validator->fails()) {
            return [];
        }

        return self::query()->whereJsonContains('user_id', $userId)->orderBy('timestamp', 'desc')->get();
    }

    public static function parseEmail($userId, $deleted = []): array
    {
        $messages = self::fetchEmailFromDB($userId);
        $limit = 50;
        $count = 1;
        $response = [
            'data' => [],
            'notifications' => [],
        ];

        foreach ($messages as $message) {

            if (in_array($message['message_id'], $deleted)) {
                // If it exists, delete the matching record from the 'emails' table
                Email::query()->where('message_id', $message['message_id'])->delete();

                continue;
            }

            $blocked = false;

            $timestamp = $message['timestamp'];
            $carbonTimestamp = Date::parse($timestamp, 'UTC');
            $obj = [];
            $obj['subject'] = $message['subject'];
            $obj['to'] = $message['to'];
            $obj['sender_name'] = $message['from_name'];
            $obj['sender_email'] = $message['from_email'];
            $obj['timestamp'] = $message['timestamp'];
            $obj['date'] = $carbonTimestamp->format('d M Y h:i A');
            $obj['datediff'] = $carbonTimestamp->diffForHumans(Date::now('UTC'));
            $obj['id'] = $message['message_id'];
            $obj['content'] = $message['body_html'];
            $obj['contentText'] = $message['body_text'];
            $obj['attachments'] = [];
            $obj['is_seen'] = $message['is_seen'];
            $obj['sender_photo'] = self::chooseColor(strtoupper(substr((string) $message['from_name'] ?: (string) $message['from_email'], 0, 1)));

            $domain = explode('@', (string) $obj['sender_email'])[1];
            $blocked = in_array($domain, json_decode((string) config('app.settings.configuration_settings'))->blocked_domains);
            if ($blocked) {
                $obj['subject'] = __('Blocked');
                $obj['content'] = __('Emails from').' '.$domain.' '.__('are blocked by Admin');
                $obj['contentText'] = __('Emails from').' '.$domain.' '.__('are blocked by Admin');
            }

            if (count($message['attachments']) > 0 && ! $blocked) {
                $obj['attachments'] = $message['attachments'];

            }

            $response['data'][] = $obj;
            if (! $message['is_seen']) {
                $response['notifications'][] = [
                    'subject' => $obj['subject'],
                    'sender_name' => $obj['sender_name'],
                    'sender_email' => $obj['sender_email'],
                ];
                if (config('app.zemail_log')) {
                    file_put_contents(storage_path('logs/zemail.csv'), request()->ip().','.date('Y-m-d h:i:s a').','.$obj['sender_email'].','.$email.PHP_EOL, FILE_APPEND);
                }
            }
            PremiumEmail::query()->where('message_id', $message['message_id'])->update(['is_seen' => true]);
            if (++$count > $limit) {
                break;
            }
        }

        return $response;
    }
}
