<?php

declare(strict_types=1);

namespace SbpJm\FlarumMSTeamsWebhook\Support;

use Flarum\Discussion\Discussion;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Post\Post;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\User;

class NotificationPayloadFactory
{
    public function __construct(
        protected SettingsRepositoryInterface $settings
    ) {}

    /**
     * Build the payload for Microsoft Teams Activity Feed.
     *
     * Informational notification that opens the Teams app side pane
     * and marks the activity item as read.
     *
     * @return array<string, mixed>
     */
    public function make(User $recipient, BlueprintInterface $blueprint): array
    {
        // Activity Feed type (informational, but clickable via /l/entity)
        $activityType = 'systemDefault';

        $forumName = trim((string) $this->settings->get('forum_title', 'sbp forum')) ?: 'sbp forum';

        // Resolve dynamic data
        $discussionTitle = $this->resolveDiscussionTitle($blueprint) ?? $forumName;
        $previewSnippet  = $this->buildPreviewText($blueprint);
        $reasonText      = $this->buildReasonTextEn($blueprint);

        // Teams App + Personal Tab (THIS is what makes it clickable & read)
        $teamsAppId    = 'd92b1be6-ea92-46b1-bcb0-c08ffdd1a61a';
        $teamsEntityId = '8ffe419f-ca44-4627-a4b2-f223da2d07aa';

        // Opens the app side pane and marks the activity as read
		$teamsTabLink = sprintf(
			'https://teams.microsoft.com/l/entity/%s/%s?webUrl=%s',
			$teamsAppId,
			$teamsEntityId,
			rawurlencode('https://forum.sbp.de/static/flarum-notify.html?v=2')
		);
        return [
            'topic' => [
                'source' => 'text',
                'value'  => $discussionTitle,
                'webUrl' => $teamsTabLink,
            ],
            'activityType' => $activityType,
            'previewText' => [
                'content' => mb_substr($previewSnippet, 0, 150),
            ],
            'templateParameters' => [
                [
                    'name'  => 'systemDefaultText',
                    'value' => $reasonText,
                ],
            ],
        ];
    }

    /**
     * Resolve the discussion title from the notification subject.
     */
    protected function resolveDiscussionTitle(BlueprintInterface $blueprint): ?string
    {
        $subject = $blueprint->getSubject();

        if ($subject instanceof Discussion) {
            return (string) $subject->title;
        }

        if ($subject instanceof Post && $subject->discussion) {
            return (string) $subject->discussion->title;
        }

        return null;
    }

    /**
     * Resolve the URL to the discussion or specific post.
     * (Not used for navigation in Teams, but kept for completeness.)
     */
    protected function resolveSubjectUrl(BlueprintInterface $blueprint): ?string
    {
        $baseUrl = rtrim(
            (string) $this->settings->get('sbp-jm-msteams-webhook.forum_base_url', ''),
            '/'
        );

        if ($baseUrl === '') {
            return null;
        }

        $subject = $blueprint->getSubject();

        if ($subject instanceof Discussion) {
            return sprintf('%s/d/%s', $baseUrl, $subject->id);
        }

        if ($subject instanceof Post) {
            $discussionId = $subject->discussion_id;
            $postNumber   = $subject->number;

            if ($discussionId !== null && $postNumber !== null) {
                return sprintf('%s/d/%s/%s', $baseUrl, $discussionId, $postNumber);
            }
        }

        return $baseUrl;
    }

    /**
     * English reason text for Activity Feed.
     */
    protected function buildReasonTextEn(BlueprintInterface $blueprint): string
    {
        return match ($blueprint::getType()) {
            'newPost'           => 'There was a new reply in a discussion you are following',
            'postMentioned'     => 'You were mentioned in a post',
            'userMentioned'     => 'You were mentioned',
            'postLiked'         => 'Your post was liked',
            'discussionRenamed' => 'A discussion was renamed',
            default             => 'New forum activity',
        };
    }

    /**
     * Build a short preview snippet shown in the Activity Feed.
     */
    protected function buildPreviewText(BlueprintInterface $blueprint): string
    {
        if ($blueprint::getType() === 'teamsTest') {
            return 'Flarum → Teams test notification sent successfully';
        }

        $actor = $blueprint->getFromUser();
        $actorName = $actor instanceof User
            ? (string) ($actor->display_name ?? $actor->username ?? 'Someone')
            : 'Someone';

        $type    = $blueprint::getType();
        $subject = $blueprint->getSubject();

        $subjectTitle = null;
        if ($subject instanceof Discussion) {
            $subjectTitle = (string) $subject->title;
        } elseif ($subject instanceof Post && $subject->discussion) {
            $subjectTitle = (string) $subject->discussion->title;
        }

        $text = match ($type) {
            'newPost'           => sprintf('%s replied to a discussion', $actorName),
            'postMentioned'     => sprintf('%s mentioned you in a post', $actorName),
            'userMentioned'     => sprintf('%s mentioned you', $actorName),
            'postLiked'         => sprintf('%s liked your post', $actorName),
            'discussionRenamed' => sprintf('%s renamed a discussion', $actorName),
            default             => sprintf('%s: new forum activity', $actorName),
        };

        if ($subjectTitle) {
            $text .= ' – ' . $subjectTitle;
        }

        return mb_substr($text, 0, 150);
    }
}