<?php

namespace FSPoster\App\SocialNetworks\Twitter\App\Repositories;

use FSPoster\App\Models\Channel;
use FSPoster\App\Models\ChannelSession;
use FSPoster\App\Providers\DB\Collection;
use FSPoster\App\Providers\DB\DB;
use Throwable;

class TwitterCommentRepository
{
    private string $socialNetworkSlug;

    public function __construct(string $socialNetworkSlug)
    {
        $this->socialNetworkSlug = $socialNetworkSlug;
    }

    /**
     * @param string[] $twitterCommentIds
     * @return array<int, array{meta_value: string, comment_id: string}>
     */
    public function findWpCommentIdsByTwitterCommentIds(array $twitterCommentIds): array
    {
        if (empty($twitterCommentIds)) {
            return [];
        }

        $placeholders = implode(',', array_fill(0, count($twitterCommentIds), '%s'));

        return DB::DB()->get_results(
            DB::DB()->prepare(
                'SELECT meta_value, comment_id FROM ' . DB::WPtable('commentmeta', true)
                . ' WHERE meta_key=\'fsp_twitter_comment_id\' AND meta_value IN (' . $placeholders . ')',
                $twitterCommentIds
            ),
            ARRAY_A
        );
    }

    public function findChannelById(int $channelId): ?Collection
    {
        return Channel::withoutGlobalScope('my_channels')->where('id', $channelId)->fetch();
    }

    /**
     * @return Channel[]
     */
    public function getActiveTwitterChannels(): array
    {
        return Channel::withoutGlobalScope('my_channels')
            ->where('channel_type', 'account')
            ->where('is_deleted', 0)
            ->where('status', 1)
            ->where(
                'channel_session_id',
                'in',
                ChannelSession::query()->where('social_network', $this->socialNetworkSlug)
                    ->where('method', 'in', ['app', 'cookie'])
                    ->select('id', true)
            )
            ->select('id')
            ->fetchAll();
    }

    public function getRecentSuccessfulSchedules(array $channelIds, array $postTypes, string $sendTimeFrom): array
    {
        $schedulesSql = DB::raw('SELECT tb1.id, tb1.channel_id, tb1.wp_post_id, tb1.remote_post_id FROM ' . DB::table('schedules') . ' tb1
            LEFT JOIN ' . DB::WPtable('posts', true) . ' tb2 ON tb1.wp_post_id = tb2.ID
            WHERE status=\'success\'
            AND tb1.channel_id IN (
            ' . implode(',', array_fill(0, count($channelIds), '%s')) . ')
            AND tb2.post_type IN (' . implode(',', array_fill(0, count($postTypes), '%s')) . ')
            AND tb1.send_time >= %s', [...$channelIds, ...$postTypes, $sendTimeFrom]);

        return DB::DB()->get_results($schedulesSql, ARRAY_A);
    }

    public function getLastCommentFetchDate(int $wpPostId, int $scheduleId): string
    {
        return (string)get_post_meta($wpPostId, 'fsp_twitter_last_comment_fetch_date_' . $scheduleId, true);
    }

    public function updateLastCommentFetchDate(int $wpPostId, int $scheduleId, int $timestamp): void
    {
        update_post_meta($wpPostId, 'fsp_twitter_last_comment_fetch_date_' . $scheduleId, $timestamp);
    }

    public function findWpCommentIdByTwitterParentId(int $postId, string $twitterParentId): int
    {
        $result = get_comments([
            'post_id'    => $postId,
            'fields'     => 'ids',
            'number'     => 1,
            'meta_key'   => 'fsp_twitter_comment_id',
            'meta_value' => $twitterParentId,
        ]);

        return (int)reset($result);
    }

    public function insertWpComment(array $commentData): ?int
    {
        try {
            $insertId = wp_new_comment($commentData, true);
        } catch (Throwable $e) {
            return null;
        }

        return is_int($insertId) ? $insertId : null;
    }

    public function addWpCommentMeta(int $commentId, string $twitterCommentId): void
    {
        add_comment_meta($commentId, 'fsp_twitter_comment_id', $twitterCommentId, true);
    }
}
