import { validatePathSegment } from '@/lib/core/security/input-validation'
import type { RedditCommentsParams, RedditCommentsResponse } from '@/tools/reddit/types'
import { normalizeSubreddit } from '@/tools/reddit/utils'
import type { ToolConfig } from '@/tools/types'

export const getCommentsTool: ToolConfig<RedditCommentsParams, RedditCommentsResponse> = {
  id: 'reddit_get_comments',
  name: 'Get Reddit Comments',
  description: 'Fetch comments from a specific Reddit post',
  version: '1.0.0',

  oauth: {
    required: true,
    provider: 'reddit',
  },

  params: {
    accessToken: {
      type: 'string',
      required: true,
      visibility: 'hidden',
      description: 'Access token for Reddit API',
    },
    postId: {
      type: 'string',
      required: true,
      visibility: 'user-or-llm',
      description: 'The ID of the Reddit post to fetch comments from (e.g., "abc123")',
    },
    subreddit: {
      type: 'string',
      required: true,
      visibility: 'user-or-llm',
      description: 'The subreddit where the post is located (e.g., "technology", "programming")',
    },
    sort: {
      type: 'string',
      required: false,
      visibility: 'user-or-llm',
      description:
        'Sort method for comments: "confidence", "top", "new", "controversial", "old", "random", "qa" (default: "confidence")',
    },
    limit: {
      type: 'number',
      required: false,
      visibility: 'user-or-llm',
      description: 'Maximum number of comments to return (e.g., 25). Default: 50, max: 100',
    },
    depth: {
      type: 'number',
      required: false,
      visibility: 'user-or-llm',
      description: 'Maximum depth of subtrees in the thread (controls nested comment levels)',
    },
    context: {
      type: 'number',
      required: false,
      visibility: 'user-or-llm',
      description: 'Number of parent comments to include',
    },
    showedits: {
      type: 'boolean',
      required: false,
      visibility: 'user-or-llm',
      description: 'Show edit information for comments',
    },
    showmore: {
      type: 'boolean',
      required: false,
      visibility: 'user-or-llm',
      description: 'Include "load more comments" elements in the response',
    },
    threaded: {
      type: 'boolean',
      required: false,
      visibility: 'user-or-llm',
      description: 'Return comments in threaded/nested format',
    },
    truncate: {
      type: 'number',
      required: false,
      visibility: 'user-or-llm',
      description: 'Integer to truncate comment depth',
    },
    comment: {
      type: 'string',
      required: false,
      visibility: 'user-or-llm',
      description: 'ID36 of a comment to focus on (returns that comment thread)',
    },
  },

  request: {
    url: (params: RedditCommentsParams) => {
      const subreddit = normalizeSubreddit(params.subreddit)
      const sort = params.sort || 'confidence'
      const limit = Math.min(Math.max(1, params.limit ?? 50), 100)

      // Build URL with query parameters
      const urlParams = new URLSearchParams({
        sort: sort,
        limit: limit.toString(),
        raw_json: '1',
      })

      // Add comment-specific parameters if provided
      if (params.depth !== undefined) urlParams.append('depth', Number(params.depth).toString())
      if (params.context !== undefined)
        urlParams.append('context', Number(params.context).toString())
      if (params.showedits !== undefined) urlParams.append('showedits', params.showedits.toString())
      if (params.showmore !== undefined) urlParams.append('showmore', params.showmore.toString())
      if (params.threaded !== undefined) urlParams.append('threaded', params.threaded.toString())
      if (params.truncate !== undefined)
        urlParams.append('truncate', Number(params.truncate).toString())

      if (params.comment) urlParams.append('comment', params.comment)

      // Validate postId to prevent path traversal
      const postId = params.postId.trim()
      const postIdValidation = validatePathSegment(postId, { paramName: 'postId' })
      if (!postIdValidation.isValid) {
        throw new Error(postIdValidation.error)
      }

      // Build URL using OAuth endpoint
      return `https://oauth.reddit.com/r/${subreddit}/comments/${postId}?${urlParams.toString()}`
    },
    method: 'GET',
    headers: (params: RedditCommentsParams) => {
      if (!params.accessToken?.trim()) {
        throw new Error('Access token is required for Reddit API')
      }

      return {
        Authorization: `Bearer ${params.accessToken}`,
        'User-Agent': 'sim-studio/1.0 (https://github.com/simstudioai/sim)',
        Accept: 'application/json',
      }
    },
  },

  transformResponse: async (response: Response, requestParams?: RedditCommentsParams) => {
    const data = await response.json()

    // Extract post data (first element in the array)
    const postData = data[0]?.data?.children?.[0]?.data || {}

    // Extract and transform comments (second element in the array)
    const commentsData = data[1]?.data?.children || []

    // Recursive function to process nested comments
    const processComments = (comments: any[]): any[] => {
      return comments
        .map((comment) => {
          const commentData = comment.data

          // Skip non-comment items like "more" items
          if (!commentData || comment.kind !== 't1') {
            return null
          }

          // Process nested replies if they exist
          const replies = commentData.replies?.data?.children
            ? processComments(commentData.replies.data.children)
            : []

          return {
            id: commentData.id ?? '',
            name: commentData.name ?? '',
            author: commentData.author || '[deleted]',
            body: commentData.body ?? '',
            created_utc: commentData.created_utc ?? 0,
            score: commentData.score ?? 0,
            permalink: commentData.permalink
              ? `https://www.reddit.com${commentData.permalink}`
              : '',
            replies: replies.filter(Boolean),
          }
        })
        .filter(Boolean)
    }

    const comments = processComments(commentsData)

    return {
      success: true,
      output: {
        post: {
          id: postData.id ?? '',
          name: postData.name ?? '',
          title: postData.title ?? '',
          author: postData.author || '[deleted]',
          selftext: postData.selftext ?? '',
          created_utc: postData.created_utc ?? 0,
          score: postData.score ?? 0,
          permalink: postData.permalink ? `https://www.reddit.com${postData.permalink}` : '',
        },
        comments: comments,
      },
    }
  },

  outputs: {
    post: {
      type: 'object',
      description: 'Post information including ID, title, author, content, and metadata',
      properties: {
        id: { type: 'string', description: 'Post ID' },
        name: { type: 'string', description: 'Thing fullname (t3_xxxxx)' },
        title: { type: 'string', description: 'Post title' },
        author: { type: 'string', description: 'Post author' },
        selftext: { type: 'string', description: 'Post text content' },
        score: { type: 'number', description: 'Post score' },
        created_utc: { type: 'number', description: 'Creation timestamp' },
        permalink: { type: 'string', description: 'Reddit permalink' },
      },
    },
    comments: {
      type: 'array',
      description: 'Nested comments with author, body, score, timestamps, and replies',
      items: {
        type: 'object',
        properties: {
          id: { type: 'string', description: 'Comment ID' },
          name: { type: 'string', description: 'Thing fullname (t1_xxxxx)' },
          author: { type: 'string', description: 'Comment author' },
          body: { type: 'string', description: 'Comment text' },
          score: { type: 'number', description: 'Comment score' },
          created_utc: { type: 'number', description: 'Creation timestamp' },
          permalink: { type: 'string', description: 'Comment permalink' },
          replies: {
            type: 'array',
            description: 'Nested reply comments',
            items: { type: 'object', description: 'Nested comment with same structure' },
          },
        },
      },
    },
  },
}
