<?php
require_once '../src/AccessToken.php';
require_once '../src/Database.php';

class EmailTicketHandler
{
    private static $conn;
    private static $accessToken;
    private static $clientEndpoint;

    public static function init($bitrixUserId)
    {
        if (!self::$conn) {
            self::$conn = Database::getInstance();
        }

        $tokenData = AccessToken::getAccessTokenByUserId($bitrixUserId);
        self::$accessToken = $tokenData['access_token'];
        self::$clientEndpoint = $tokenData['client_endpoint'];
    }

    public static function getAllUserProjects($bitrix24UserId)
    {
        $conn = self::$conn ?? Database::getInstance();
        $projects = [];

        $sql = "SELECT id ,project_id,project_type, folder_id, query_email FROM projects WHERE bitrix24_user_id = ? AND flow_type='external'";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("i", $bitrix24UserId);
        $stmt->execute();
        $result = $stmt->get_result();

        while ($row = $result->fetch_assoc()) {
            $projects[] = [
                'project_id'  => $row['project_id'],
                'folder_id'   => $row['folder_id'],
                'query_email' => $row['query_email'],
                'project_local_id' => $row['id'],
                'issue_type' => $row['project_type'],
            ];
        }

        $stmt->close();

        if (empty($projects)) {
            return ['error' => 'No projects found for Bitrix user ID: ' . $bitrix24UserId];
        }

        return $projects;
    }

    public static function getOrInsertUserId($email, $name, $bitrix24UserId)
    {
        $conn = self::$conn ?? Database::getInstance();

        $stmt = $conn->prepare("SELECT id FROM users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            $row = $result->fetch_assoc();
            $userId = $row['id'];
            $stmt->close();
            return $userId;
        }

        $stmt = $conn->prepare("INSERT INTO users (email, name, bitrix24_user_id) VALUES (?, ?, ?)");
        $stmt->bind_param("ssi", $email, $name, $bitrix24UserId);
        $stmt->execute();
        $userId = $stmt->insert_id;
        $stmt->close();

        return $userId;
    }

    public static function callApi($method, $params = [])
    {
        if (!self::$clientEndpoint || !self::$accessToken) {
            return ['error' => 'Client endpoint or access token not initialized.'];
        }

        $baseUrl = self::$clientEndpoint . $method . "?auth=" . self::$accessToken;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $baseUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
    public static function fetchUnreadEmailsForToday($bitrix24UserId)
    {
        EmailTicketHandler::init($bitrix24UserId);
        // Ensure the class is initialized (optional check)
        if (!self::$clientEndpoint || !self::$accessToken) {
            return ['error' => 'Access token or client endpoint not set. Please run init() first.'];
        }

        $todayStart = date('Y-m-d') . "T00:00:00+03:00";
        $todayEnd   = date('Y-m-d') . "T23:59:59+03:00";

        $params = [
            'filter' => [
                'TYPE_ID'   => 4,
                '>=CREATED' => $todayStart,
                '<=CREATED' => $todayEnd,
                'DIRECTION' => 1,
                'COMPLETED' => 'N',
            ],
            'select' => [
                'ID',
                'SUBJECT',
                'DESCRIPTION',
                'CREATED',
                'OWNER_ID',
                'OWNER_TYPE_ID',
                'RESPONSIBLE_ID',
                'AUTHOR_ID',
                'COMMUNICATIONS',
                'SETTINGS',
                'FILES',
                'PRIORITY'
            ],
            'order' => ['CREATED' => 'DESC']
        ];

        $method = '/crm.activity.list.json';
        $response = self::callApi($method, $params);

        return $response['result'] ?? [];
    }

    public static function  clean_html($html)
    {
        $html = preg_replace('#<style.*?>.*?</style>#si', '', $html);
        $html = preg_replace('#<script.*?>.*?</script>#si', '', $html);
        $html = preg_replace('#<!--.*?-->#s', '', $html);
        $html = preg_replace('#<blockquote.*?>.*?</blockquote>#si', '', $html);
        $html = strip_tags($html);
        $html = html_entity_decode($html, ENT_QUOTES, 'UTF-8');
        $html = preg_replace('/On\s.+?wrote:/is', '', $html);
        $html = preg_replace('/(From:|To:|Subject:|Date:).*/i', '', $html);
        $html = preg_replace('/-----Original Message-----/i', '', $html);
        $html = preg_replace('/-{2,}\s*Forwarded message\s*-{2,}/i', '', $html);
        $html = preg_replace('/\n>+.*/', '', $html);
        $html = preg_replace('/\s+/', ' ', $html);
        return trim($html);
    }

    public static function normalize_subject($subject)
    {
        return strtolower(trim($subject));
    }
    private static function getNextResponsibleUser($internalProjectId)
    {
        $stmt = self::$conn->prepare("SELECT responsible_bitrix_id FROM project_responsible_users WHERE project_id = ? ORDER BY last_assigned_at ASC LIMIT 1");
        $stmt->bind_param("i", $internalProjectId);
        $stmt->execute();
        $result = $stmt->get_result();
        $user = $result->fetch_assoc();
        if (!$user) return null;

        $update = self::$conn->prepare("UPDATE project_responsible_users SET last_assigned_at = NOW() WHERE responsible_bitrix_id = ?");
        $update->bind_param("i", $user['responsible_bitrix_id']);
        $update->execute();

        return $user['responsible_bitrix_id'];
    }
    private static function createBitrixTask($taskData)
    {
        for ($i = 0; $i < 3; $i++) {
            $response = self::callApi("tasks.task.add.json", $taskData);
            if (isset($response['result']['task']['id'])) {
                return $response['result']['task']['id'];
            }
            sleep(1);
        }
        return null;
    }



    public static function processUnreadEmails($bitrix24UserId)
    {
        $results = [];

        if (!$bitrix24UserId) {
            return ['error' => 'User ID not provided.'];
        }

        $projects = self::getAllUserProjects($bitrix24UserId);
        $emails = self::fetchUnreadEmailsForToday($bitrix24UserId);

        if (empty($emails)) {
            return ['message' => 'No unread emails found.'];
        }

        foreach ($emails as $email) {
            $receiverEmail = $email['SETTINGS']['EMAIL_META']['__email'] ?? '';
            $replyTo = $email['SETTINGS']['EMAIL_META']['replyTo'] ?? '';
            $emailName = $email['COMMUNICATIONS'][0]['ENTITY_SETTINGS']['NAME'] ?? '';
            $emailNameLast = $email['COMMUNICATIONS'][0]['ENTITY_SETTINGS']['LAST_NAME'] ?? '';
            $fullName= $emailName." ".$emailNameLast;

            $matchedProject = null;
            foreach ($projects as $project) {
                if (strtolower($receiverEmail) === strtolower($project['query_email'])) {
                    $matchedProject = $project;
                    break;
                }
            }

            if (!$matchedProject) {
                continue;
            }

            $projectId = $matchedProject['project_id'];
            $folderId = $matchedProject['folder_id'];
            $internalProjectId = $matchedProject['project_local_id'];
            $issueType = $matchedProject['issue_type'];

            $emailBody = self::clean_html($email['DESCRIPTION']);
            $normalizedSubject = self::normalize_subject($email['SUBJECT']);
            if (stripos($normalizedSubject, 're:') !== false) {
                continue;
            }

            $fileIds = [];
            if (!empty($email['FILES'])) {
                foreach ($email['FILES'] as $file) {
                    $fileIds[] = $file['id'];
                }
            }

            $communications = $email['COMMUNICATIONS'] ?? [];
            $senderEmail = '';
            foreach ($communications as $comm) {
                if ($comm['TYPE'] === 'EMAIL') {
                    $senderEmail = $comm['VALUE'];
                    break;
                }
            }
            $ticketUserName = "Email user";
            $ticketUserId = EmailTicketHandler::getOrInsertUserId($senderEmail, $ticketUserName, $bitrix24UserId);
            $results[] = [
                'email_id' => $email['ID'],
                'full_name' => $fullName,
                'replyTo' =>  $replyTo,
                'subject' => $email['SUBJECT'],
                'ticket_user_id' => $ticketUserId,
                'normalized_subject' => $normalizedSubject,
                'body' => $emailBody,
                'receiver_email' => $receiverEmail,
                'sender_email' => $senderEmail,
                'file_ids' => $fileIds,
                'project_id' => $projectId,
                'project_folder_id' => $folderId,
                'internal_project_id' => $internalProjectId,
                'issue_type' => $issueType,
                'created_at' => $email['CREATED'],
                'priority' => $email['PRIORITY'],
                'responsible_id' => $email['RESPONSIBLE_ID'] ?? null,
                'owner_type_id' => $email['OWNER_TYPE_ID'] ?? null,
                'owner_id' => $email['OWNER_ID'] ?? null
            ];
        }

        return $results;
    }
    public static function handleTicket($postData, $fileData)
    {
        if (empty($postData['bitrix24_user_id'])) {
            return ['success' => false, 'message' => 'Bitrix24 user ID missing'];
        }

        self::init($postData['bitrix24_user_id']);
        $bitrixUserId   = $postData['bitrix24_user_id'];

        $emailId    = htmlspecialchars(trim($postData['email_id']));
        $description    = htmlspecialchars(trim($postData['description']));
        $subject        = htmlspecialchars(trim($postData['subject']));
        $ticketUserId   = htmlspecialchars(trim($postData['ticket_user_id']));
        $status         = 'New';
        $source         = 'email';
        $ticketId       = 'No';
        $userEmail      = $postData['sender_email'];
        $entityId      = $postData['owner_id'];
        $entityType      = $postData['OWNER_TYPE_ID'];
        $bitrixDeadline      = $postData['bitrixDeadline'];
        $userName       = null;
        $phone          = null;

        $projectType       = $postData['project_type'] ?? '';
        $bitrixProjectId   = intval($postData['project_id'] ?? 0);
        $folderId          = $postData['folder_id'] ?? '';
        $internalProjectId = intval($postData['id'] ?? 0);

        $responsibleId = self::getNextResponsibleUser($internalProjectId);
        $priorityLabel = strtolower(trim($postData['priority']));
        $priorityMap = [
            'low'    => 1,
            'medium' => 2,
            'high'   => 3,
        ];
        $priority = $priorityMap[$priorityLabel] ?? 1;
        if (!$responsibleId) {
            return ['success' => false, 'message' => 'No responsible user available'];
        }

        $bitrixTask = [
            "fields" => [
                "TITLE"         => "Ticket: $subject",
                "DESCRIPTION"   => $description,
                "RESPONSIBLE_ID" => $responsibleId,
                "DESCRIPTION_IN_BBCODE" => "Y", 
                "GROUP_ID"      => $bitrixProjectId,
                "PRIORITY"      => $priorityMap,
                "TAGS"          => [$projectType],
                "DEADLINE" => $bitrixDeadline
            ]
        ];

        $task_id = self::createBitrixTask($bitrixTask);
        if (!$task_id) {
            return ['success' => false, 'message' => 'Bitrix24 task creation failed'];
        }
        self::callApi("im.message.add", [
            "USER_ID" => $responsibleId,
            "MESSAGE" => "New task assigned to you:Task id .$task_id.  *$subject*.\nPlease check your task list.",
            "SYSTEM" => "Y"
        ]);

        // Attach files if file_ids are provided from Bitrix email
        if (!empty($fileData['bitrix_file_ids'])) {
            foreach ($fileData['bitrix_file_ids'] as $fileId) {
                self::callApi("tasks.task.files.attach", [
                    "taskId" => $task_id,
                    "fileId" => $fileId
                ]);
            }
        }
        if ($emailId) {
            $update_params = [
                "ID" => $emailId,
                "FIELDS" => [
                    "COMPLETED" => "Y"
                ]
            ];
        }
        $method = '/crm.activity.update.json';
        $response = self::callApi($method, $update_params);
        $stmt = self::$conn->prepare("
        INSERT INTO external_ticket (
            ticket_id, task_id, bitrix_user_id, ticket_user_id, project_id,
            name, phone, email, subject, issue_type,
            priority, sorce, description, status,OWNER_ID,OWNER_TYPE_ID,responsible_id,email_parent_id,
            created_at, updated_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?, NOW(), NOW())
    ");

        $stmt->bind_param(
            "siiiisssssssssiisi",
            $ticketId,
            $task_id,
            $bitrixUserId,
            $ticketUserId,
            $bitrixProjectId,
            $userName,
            $phone,
            $userEmail,
            $subject,
            $projectType,
            $priority,
            $source,
            $description,
            $status,
            $entityId,
            $entityType,
            $responsibleId,
            $emailId
        );

        if ($stmt->execute()) {
            return ['success' => true, 'message' => 'Ticket created successfully', 'task_id' => $task_id];
        } else {
            return ['success' => false, 'message' => 'Database error while saving ticket'];
        }
    }
}
function extractReportDetails($text) {
    $pattern = '/A new (.*?) report for (.*?) has been.*?due by ([\d\w\s,]+at \d{2}:\d{2})/';
    if (preg_match($pattern, $text, $matches)) {
        return [
            'report_type' => $matches[1],
            'report_location' => $matches[2],
            'due_date_time' => $matches[3],
        ];
    }
    return [
        'error' => true,
        'message' => 'Failed to extract details from the text.'
    ];
}
function html_to_bbcode_description($text) {
    $text = str_replace('<strong>', '[B]', $text);
    $text = str_replace('</strong>', '[/B]', $text);
    $text = str_replace('<br>', "\n", $text);
    $text = strip_tags($text, '[B]');
    return $text;
}
$bitrix24UserId = isset($_GET['user_id']) ? (int)$_GET['user_id'] : 0;
$emailTickets = EmailTicketHandler::processUnreadEmails($bitrix24UserId);

if (isset($emailTickets['error']) || isset($emailTickets['message'])) {
    echo "<pre>";
    print_r($emailTickets);
    exit;
}

$results = [];
foreach ($emailTickets as $emailData) {
    
    $reportResult = extractReportDetails($emailData['body']);
    
    $customDescription = '';
    $customSubject = '';
    $createTask = true;
    $bitrixDeadline = '';

    if ($bitrix24UserId == 10 && !empty($reportResult['report_location'])) {
        $replyTo = $emailData['sender_email'];
        $emailName = $emailData['full_name'];

        $createdDate = new DateTime("now", new DateTimeZone("Asia/Kolkata"));
        $createdFormatted = $createdDate->format("jS F, Y \a\\t H:i");

        $dueDate = DateTime::createFromFormat("jS F, Y \a\\t H:i", $reportResult['due_date_time'], new DateTimeZone("Europe/London"));
        if ($dueDate) {
            $dueDate->setTimezone(new DateTimeZone("Asia/Kolkata"));
            $dueFormatted = $dueDate->format("jS F, Y \a\\t H:i");

            $dueDate->setTimezone(new DateTimeZone("UTC"));
            $bitrixDeadline = $dueDate->format("Y-m-d\TH:i:sP");
        } else {
            $dueFormatted = $reportResult['due_date_time'];
        }

        $customSubject = $reportResult['report_location'];

        $taskDescriptionHtml = <<<HTML
        <strong>Clerk Name:</strong> {$emailName}<br>
        <strong>Clerk Email:</strong> {$replyTo}<br>
        <strong>Report Type:</strong> {$reportResult['report_type']}<br>
        <strong>Property:</strong> {$reportResult['report_location']}<br>
        <strong>Created On:</strong> {$createdFormatted}<br>
        <strong>Due on:</strong> {$dueFormatted}
HTML;

        $customDescription = html_to_bbcode_description($taskDescriptionHtml);
    } elseif ($bitrix24UserId == 10) {
        $createTask = false;

        echo "Skipped task creation for user id 10 as report_location is empty.\n";

        // --- Placeholder: Send custom email to user id 10 here ---
        /*
        sendCustomEmail([
            'to' => $emailData['sender_email'],
            'subject' => 'Unable to create task due to missing report location',
            'message' => 'Dear user, the report location is missing in your ticket. Please check and resend.'
        ]);
        */
        continue; // Skip task creation
    }

    $postData = [
        'bitrix24_user_id' => $bitrix24UserId,
        'project_type'     => $emailData['issue_type'],
        'project_id'       => $emailData['project_id'],
        'folder_id'        => $emailData['project_folder_id'],
        'id'               => $emailData['internal_project_id'],
        'priority'         => $emailData['priority'],
        'description'      => $customDescription ?: $emailData['body'],
        'subject'          => $customSubject ?: $emailData['normalized_subject'],
        'ticket_user_id'   => $emailData['ticket_user_id'],
        'email_id'         => $emailData['email_id'],
        'sender_email'     => $emailData['sender_email'],
        'OWNER_TYPE_ID'    => $emailData['owner_type_id'],
        'owner_id'         => $emailData['owner_id'],
        'bitrixDeadline'   => $bitrixDeadline ?: ''
    ];

    $fileData = [
        'bitrix_file_ids' => $emailData['file_ids'] ?? []
    ];

   

     $result = EmailTicketHandler::handleTicket($postData, $fileData);
    $results[] = $result;
}

echo "<pre>";
print_r($results);
