import { z, IntegrationDefinition } from '@botpress/sdk'

export default new IntegrationDefinition({
  name: 'canny',
  version: '0.2.3',
  title: 'Canny',
  description: 'Connect your Botpress bot to Canny for feature request management and customer feedback collection',
  readme: 'hub.md',
  icon: 'icon.svg',
  configuration: {
    schema: z.object({
      apiKey: z.string().title('API Key').describe('Your Canny API key'),
    }),
  },
  channels: {
    posts: {
      title: 'Posts',
      description: 'Channel for Canny posts and comments',
      messages: {
        text: {
          schema: z.object({
            text: z.string(),
          }),
        },
        image: {
          schema: z.object({
            imageUrl: z.string(),
            caption: z.string().optional(),
          }),
        },
      },
      conversation: {
        tags: {
          cannyPostId: {
            title: 'Post ID',
            description: 'The Canny post ID',
          },
          cannyBoardId: {
            title: 'Board ID',
            description: 'The Canny board ID',
          },
        },
      },
      message: {
        tags: {
          cannyType: {
            title: 'Type',
            description: 'Whether this is a post or comment',
          },
          cannyPostId: {
            title: 'Post ID',
            description: 'The associated post ID',
          },
          cannyCommentId: {
            title: 'Comment ID',
            description: 'The comment ID (if applicable)',
          },
        },
      },
    },
  },
  actions: {
    // Post actions
    createPost: {
      title: 'Create Post',
      description: 'Create a new post in Canny',
      input: {
        schema: z.object({
          authorId: z
            .string()
            .optional()
            .title('Author Id')
            .describe('The author Id (defaults to Botpress user if not provided)'),
          boardId: z.string().title('Board Id').describe('The board Id'),
          title: z.string().title('Post Title').describe('Post title'),
          details: z.string().title('Post Details').describe('Post details'),
          byId: z.string().optional().title('By Id').describe('Admin Id who created the post'),
          categoryId: z.string().optional().title('Category Id').describe('Category Id'),
          ownerId: z.string().optional().title('Owner Id').describe('Owner Id'),
          imageURLs: z.array(z.string()).optional().title('Image URLs').describe('Image URLs'),
          eta: z.string().optional().title('ETA').describe('ETA (MM/YYYY)'),
          etaPublic: z.boolean().optional().title('ETA Public').describe('Make ETA public'),
          customFields: z.record(z.any()).optional().title('Custom Fields').describe('Custom fields'),
        }),
      },
      output: {
        schema: z.object({
          postId: z.string().title('Post ID').describe('The ID of the created post'),
        }),
      },
    },
    getPost: {
      title: 'Get Post',
      description: 'Retrieve a post by ID',
      input: {
        schema: z.object({
          postId: z.string().title('Post Id').describe('The post Id'),
          boardId: z.string().optional().title('Board Id').describe('The board Id'),
        }),
      },
      output: {
        schema: z.object({
          post: z
            .object({
              id: z.string().title('ID').describe('Post ID'),
              title: z.string().title('Title').describe('Post title'),
              details: z.string().optional().title('Details').describe('Post details'),
              authorName: z.string().optional().title('Author Name').describe('Name of the post author'),
              authorEmail: z.string().optional().title('Author Email').describe('Email of the post author'),
              boardName: z.string().title('Board Name').describe('Name of the board'),
              status: z.string().title('Status').describe('Post status'),
              score: z.number().title('Score').describe('Post score'),
              commentCount: z.number().title('Comment Count').describe('Number of comments'),
              created: z.string().title('Created').describe('Creation timestamp'),
              url: z.string().title('URL').describe('Post URL'),
            })
            .title('Post')
            .describe('The retrieved post object'),
        }),
      },
    },
    listPosts: {
      title: 'List Posts',
      description: 'List posts with optional filters',
      input: {
        schema: z.object({
          boardId: z.string().optional().title('Board Id').describe('Filter posts by board Id'),
          authorId: z.string().optional().title('Author Id').describe('Filter posts by author Id'),
          companyId: z.string().optional().title('Company Id').describe('Filter posts by company Id'),
          tagIds: z.array(z.string()).optional().title('Tag Ids').describe('Filter posts by tag Ids'),
          limit: z.number().optional().title('Limit').describe('Number of posts to return'),
          nextToken: z.number().optional().title('Next Token').describe('Token for pagination - skip this many posts'),
          search: z.string().optional().title('Search').describe('Search term to filter posts'),
          sort: z
            .enum(['newest', 'oldest', 'relevance', 'score', 'statusChanged', 'trending'])
            .optional()
            .title('Sort')
            .describe('Sort order for posts'),
          status: z.string().optional().title('Status').describe('Filter posts by status'),
        }),
      },
      output: {
        schema: z.object({
          posts: z
            .array(
              z.object({
                id: z.string().title('ID').describe('Post ID'),
                title: z.string().title('Title').describe('Post title'),
                details: z.string().optional().title('Details').describe('Post details'),
                authorName: z.string().optional().title('Author Name').describe('Name of the post author'),
                authorEmail: z.string().optional().title('Author Email').describe('Email of the post author'),
                boardName: z.string().title('Board Name').describe('Name of the board'),
                status: z.string().title('Status').describe('Post status'),
                score: z.number().title('Score').describe('Post score'),
                commentCount: z.number().title('Comment Count').describe('Number of comments'),
                created: z.string().title('Created').describe('Creation timestamp'),
                url: z.string().title('URL').describe('Post URL'),
              })
            )
            .title('Posts')
            .describe('Array of posts'),
          nextToken: z.number().optional().title('Next Token').describe('Token for next page if more posts available'),
        }),
      },
    },
    updatePost: {
      title: 'Update Post',
      description: 'Update an existing post',
      input: {
        schema: z.object({
          postId: z.string().title('Post Id').describe('The post Id'),
          title: z.string().optional().title('Title').describe('Updated post title'),
          details: z.string().optional().title('Details').describe('Updated post details'),
          eta: z.string().optional().title('ETA').describe('Updated ETA (MM/YYYY)'),
          etaPublic: z.boolean().optional().title('ETA Public').describe('Make ETA public'),
          imageURLs: z.array(z.string()).optional().title('Image URLs').describe('Updated image URLs'),
          customFields: z.record(z.any()).optional().title('Custom Fields').describe('Updated custom fields'),
        }),
      },
      output: {
        schema: z.object({}),
      },
    },
    deletePost: {
      title: 'Delete Post',
      description: 'Delete a post',
      input: {
        schema: z.object({
          postId: z.string().title('Post Id').describe('The post Id to delete'),
        }),
      },
      output: {
        schema: z.object({}),
      },
    },

    // Comment actions
    createComment: {
      title: 'Create Comment',
      description: 'Create a new comment on a post',
      input: {
        schema: z.object({
          authorId: z
            .string()
            .optional()
            .title('Author Id')
            .describe('The author Id (defaults to Botpress user if not provided)'),
          postId: z.string().title('Post Id').describe('The post Id'),
          value: z.string().title('Comment Text').describe('Comment text'),
          parentId: z.string().optional().title('Parent Id').describe('Parent comment Id for replies'),
          imageURLs: z.array(z.string()).optional().title('Image URLs').describe('Image URLs'),
          internal: z.boolean().optional().title('Internal').describe('Whether this is an internal comment'),
          shouldNotifyVoters: z.boolean().optional().title('Notify Voters').describe('Notify voters'),
          createdAt: z.string().optional().title('Created At').describe('Created timestamp'),
        }),
      },
      output: {
        schema: z.object({
          commentId: z.string().title('Comment ID').describe('The ID of the created comment'),
        }),
      },
    },
    getComment: {
      title: 'Get Comment',
      description: 'Retrieve a comment by ID',
      input: {
        schema: z.object({
          commentId: z.string().title('Comment Id').describe('The comment Id'),
        }),
      },
      output: {
        schema: z.object({
          comment: z
            .object({
              id: z.string().title('ID').describe('Comment ID'),
              value: z.string().title('Value').describe('Comment text'),
              authorName: z.string().title('Author Name').describe('Name of the comment author'),
              authorEmail: z.string().title('Author Email').describe('Email of the comment author'),
              postTitle: z.string().title('Post Title').describe('Title of the associated post'),
              postId: z.string().title('Post ID').describe('ID of the associated post'),
              created: z.string().title('Created').describe('Creation timestamp'),
              internal: z.boolean().title('Internal').describe('Whether this is an internal comment'),
              likeCount: z.number().title('Like Count').describe('Number of likes'),
            })
            .title('Comment')
            .describe('The retrieved comment object'),
        }),
      },
    },
    listComments: {
      title: 'List Comments',
      description: 'List comments with optional filters',
      input: {
        schema: z.object({
          postId: z.string().optional().title('Post Id').describe('Filter comments by post Id'),
          authorId: z.string().optional().title('Author Id').describe('Filter comments by author Id'),
          boardId: z.string().optional().title('Board Id').describe('Filter comments by board Id'),
          companyId: z.string().optional().title('Company Id').describe('Filter comments by company Id'),
          limit: z.number().optional().title('Limit').describe('Number of comments to return'),
          nextToken: z
            .number()
            .optional()
            .title('Next Token')
            .describe('Token for pagination - skip this many comments'),
        }),
      },
      output: {
        schema: z.object({
          comments: z
            .array(
              z.object({
                id: z.string().title('ID').describe('Comment ID'),
                value: z.string().title('Value').describe('Comment text'),
                authorName: z.string().title('Author Name').describe('Name of the comment author'),
                authorEmail: z.string().title('Author Email').describe('Email of the comment author'),
                postTitle: z.string().title('Post Title').describe('Title of the associated post'),
                postId: z.string().title('Post ID').describe('ID of the associated post'),
                created: z.string().title('Created').describe('Creation timestamp'),
                internal: z.boolean().title('Internal').describe('Whether this is an internal comment'),
                likeCount: z.number().title('Like Count').describe('Number of likes'),
              })
            )
            .title('Comments')
            .describe('Array of comments'),
          nextToken: z
            .number()
            .optional()
            .title('Next Token')
            .describe('Token for next page if more comments available'),
        }),
      },
    },
    deleteComment: {
      title: 'Delete Comment',
      description: 'Delete a comment',
      input: {
        schema: z.object({
          commentId: z.string().title('Comment Id').describe('The comment Id to delete'),
        }),
      },
      output: {
        schema: z.object({}),
      },
    },

    // User management actions
    createOrUpdateUser: {
      title: 'Create or Update User',
      description: 'Create a new user or update an existing one in Canny',
      input: {
        schema: z.object({
          name: z.string().min(1).max(50).title('Name').describe('User display name (required, 1-50 characters)'),
          userId: z.string().optional().title('User Id').describe('Your internal user Id'),
          email: z.string().optional().title('Email').describe('User email address'),
          avatarURL: z.string().optional().title('Avatar URL').describe('User avatar URL'),
          alias: z.string().optional().title('Alias').describe('User alias'),
          created: z.string().optional().title('Created').describe('User creation timestamp'),
          customFields: z.record(z.any()).optional().title('Custom Fields').describe('Custom fields'),
        }),
      },
      output: {
        schema: z.object({
          user: z
            .object({
              id: z.string().title('ID').describe('User ID'),
              name: z.string().title('Name').describe('User display name'),
              email: z.string().title('Email').describe('User email address'),
              avatarURL: z.string().optional().title('Avatar URL').describe('User avatar URL'),
              userId: z.string().title('User ID').describe('Your internal user ID'),
              isAdmin: z.boolean().title('Is Admin').describe('Whether the user is an admin'),
              created: z.string().title('Created').describe('User creation timestamp'),
            })
            .title('User')
            .describe('The created or updated user object'),
        }),
      },
    },
    listUsers: {
      title: 'List Users',
      description: 'List all users in your Canny workspace with pagination',
      input: {
        schema: z.object({
          limit: z
            .number()
            .min(1)
            .max(100)
            .optional()
            .title('Limit')
            .describe('Number of users to fetch (1-100, defaults to 10)'),
          nextToken: z.string().optional().title('Next Token').describe('Token for pagination from previous request'),
        }),
      },
      output: {
        schema: z.object({
          users: z
            .array(
              z.object({
                id: z.string().title('ID').describe('User ID'),
                name: z.string().title('Name').describe('User display name'),
                email: z.string().title('Email').describe('User email address'),
                avatarURL: z.string().optional().title('Avatar URL').describe('User avatar URL'),
                userId: z.string().title('User ID').describe('Your internal user ID'), // Can be empty string if user has no userId
                isAdmin: z.boolean().title('Is Admin').describe('Whether the user is an admin'),
                created: z.string().title('Created').describe('User creation timestamp'),
              })
            )
            .title('Users')
            .describe('Array of users'),
          nextToken: z.string().optional().title('Next Token').describe('Token for next page if more users available'),
        }),
      },
    },

    // Board management actions
    listBoards: {
      title: 'List Boards',
      description: 'List all boards in your Canny workspace',
      input: {
        schema: z.object({
          limit: z.number().optional().title('Limit').describe('Number of boards to fetch'),
          nextToken: z.number().optional().title('Next Token').describe('Token for pagination - skip this many boards'),
        }),
      },
      output: {
        schema: z.object({
          boards: z
            .array(
              z.object({
                id: z.string().title('ID').describe('Board ID'),
                name: z.string().title('Name').describe('Board name'),
                postCount: z.number().title('Post Count').describe('Number of posts in the board'),
                url: z.string().title('URL').describe('Board URL'),
                created: z.string().title('Created').describe('Board creation timestamp'),
              })
            )
            .title('Boards')
            .describe('Array of boards'),
          nextToken: z.number().optional().title('Next Token').describe('Token for next page if more boards available'),
        }),
      },
    },
  },
  attributes: {
    category: 'Project Management',
    guideSlug: 'canny',
    repo: 'botpress',
  },
})
