#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ================================================== #
# This file is a part of PYGPT package               #
# Website: https://pygpt.net                         #
# GitHub:  https://github.com/szczyglis-dev/py-gpt   #
# MIT License                                        #
# Created By  : Marcin Szczygliński                  #
# Updated Date: 2025.08.14 00:00:00                  #
# ================================================== #

from pygpt_net.plugin.base.config import BaseConfig, BasePlugin


class Config(BaseConfig):
    def __init__(self, plugin: BasePlugin = None, *args, **kwargs):
        super(Config, self).__init__(plugin)
        self.plugin = plugin

    def from_defaults(self, plugin: BasePlugin = None):
        # Endpoints / HTTP
        plugin.add_option(
            "api_base",
            type="text",
            value="https://api.x.com",
            label="API base",
            description="Base API URL (default https://api.x.com).",
        )
        plugin.add_option(
            "authorize_base",
            type="text",
            value="https://x.com",
            label="Authorize base",
            description="Base for OAuth authorize (default https://x.com).",
        )
        plugin.add_option(
            "http_timeout",
            type="int",
            value=30,
            label="HTTP timeout (s)",
            description="Requests timeout in seconds.",
        )

        # OAuth2 PKCE
        plugin.add_option(
            "oauth2_client_id",
            type="text",
            value="",
            label="OAuth2 Client ID",
            description="Client ID from X Developer Portal.",
            secret=True,
        )
        plugin.add_option(
            "oauth2_client_secret",
            type="text",
            value="",
            label="OAuth2 Client Secret (optional)",
            description="Only for confidential clients (Basic auth on token endpoints).",
            secret=True,
        )
        plugin.add_option(
            "oauth2_confidential",
            type="bool",
            value=False,
            label="Confidential client (use Basic auth)",
            description="Enable if your App is confidential and you want to use Basic auth with token endpoints.",
        )
        plugin.add_option(
            "oauth2_redirect_uri",
            type="text",
            value="http://127.0.0.1:8731/callback",
            label="Redirect URI",
            description="Must exactly match one of the callback URLs in your X App (including port).",
        )
        plugin.add_option(
            "oauth2_scopes",
            type="text",
            value="tweet.read users.read like.read like.write tweet.write bookmark.read bookmark.write tweet.moderate.write offline.access",
            label="Scopes",
            description="Space-separated OAuth2 scopes for Authorization Code with PKCE.",
        )
        plugin.add_option(
            "oauth2_code_verifier",
            type="text",
            value="",
            label="(auto) code_verifier",
            description="Generated by x_oauth_begin.",
            secret=True,
        )
        plugin.add_option(
            "oauth2_state",
            type="text",
            value="",
            label="(auto) state",
            description="Generated by x_oauth_begin.",
            secret=True,
        )
        plugin.add_option(
            "oauth2_access_token",
            type="textarea",
            value="",
            label="(auto) Access token",
            description="Stored user access token.",
            secret=True,
        )
        plugin.add_option(
            "oauth2_refresh_token",
            type="textarea",
            value="",
            label="(auto) Refresh token",
            description="Stored user refresh token.",
            secret=True,
        )
        plugin.add_option(
            "oauth2_expires_at",
            type="text",
            value="0",
            label="(auto) Expires at (unix)",
            description="Auto-calculated expiry time.",
            secret=False,
        )

        # App-only bearer (optional for read-only)
        plugin.add_option(
            "bearer_token",
            type="textarea",
            value="",
            label="App-only Bearer token (optional)",
            description="Optional app-only bearer for read endpoints.",
            secret=True,
        )

        # Convenience cache
        plugin.add_option(
            "user_id",
            type="text",
            value="",
            label="(auto) User ID",
            description="Cached after x_me or oauth exchange.",
        )
        plugin.add_option(
            "username",
            type="text",
            value="",
            label="(auto) Username",
            description="Cached after x_me or oauth exchange.",
        )
        plugin.add_option(
            "oauth_auto_begin",
            type="bool",
            value=True,
            label="Auto-start OAuth when required",
            description="If a command needs user token, begin PKCE flow automatically.",
        )
        plugin.add_option(
            "oauth_open_browser",
            type="bool",
            value=True,
            label="Open browser automatically",
            description="Open authorize URL in default browser.",
        )
        plugin.add_option(
            "oauth_local_server",
            type="bool",
            value=True,
            label="Use local server for OAuth",
            description="Start local HTTP server to capture redirect (requires redirect_uri = http://localhost[:port]/path).",
        )
        plugin.add_option(
            "oauth_local_timeout",
            type="int",
            value=180,
            label="OAuth local timeout (s)",
            description="How long to wait for redirect with code.",
        )
        plugin.add_option(
            "oauth_success_html",
            type="textarea",
            value="<html><body><h3>Authorization complete. You can close this window.</h3></body></html>",
            label="Success HTML",
            description="HTML shown on local callback success.",
        )
        plugin.add_option(
            "oauth_fail_html",
            type="textarea",
            value="<html><body><h3>Authorization failed.</h3></body></html>",
            label="Fail HTML",
            description="HTML shown on local callback error.",
        )
        plugin.add_option(
            "oauth_local_port",
            type="int",
            value=8731,
            label="OAuth local port (0=auto)",
            description="Local HTTP port for callback; use >1024. Must be registered in X App.",
        )

        plugin.add_option(
            "oauth_allow_port_fallback",
            type="bool",
            value=True,
            label="Allow fallback port if busy",
            description="If preferred port is busy/forbidden, pick a free local port and rebuild the redirect URL.",
        )

        # ---------------- Commands ----------------

        # Auth
        plugin.add_cmd(
            "x_oauth_begin",
            instruction="Begin OAuth2 PKCE flow (returns authorize URL).",
            params=[
                {"name": "scopes", "type": "str", "required": False, "description": "Override scopes (space-separated)"},
                {"name": "state", "type": "str", "required": False, "description": "Optional CSRF state"},
            ],
            enabled=True,
            description="Auth: begin OAuth2",
            tab="auth",
        )
        plugin.add_cmd(
            "x_oauth_exchange",
            instruction="Exchange authorization code for access/refresh tokens.",
            params=[
                {"name": "code", "type": "str", "required": True, "description": "Authorization code"},
                {"name": "state", "type": "str", "required": False, "description": "State (if used)"},
            ],
            enabled=True,
            description="Auth: exchange code",
            tab="auth",
        )
        plugin.add_cmd(
            "x_oauth_refresh",
            instruction="Refresh access token using refresh_token.",
            params=[],
            enabled=True,
            description="Auth: refresh token",
            tab="auth",
        )

        # Users
        plugin.add_cmd(
            "x_me",
            instruction="Get authorized user (requires user token).",
            params=[
                {"name": "user.fields", "type": "str", "required": False, "description": "e.g. created_at,verified,public_metrics"},
                {"name": "expansions", "type": "str", "required": False, "description": "e.g. pinned_tweet_id"},
                {"name": "tweet.fields", "type": "str", "required": False, "description": "fields of pinned tweet"},
            ],
            enabled=True,
            description="Users: me",
            tab="users",
        )
        plugin.add_cmd(
            "x_user_by_username",
            instruction="Lookup user by username.",
            params=[
                {"name": "username", "type": "str", "required": True, "description": "Handle without @"},
                {"name": "user_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "expansions", "type": "str", "required": False, "description": "Comma list"},
                {"name": "tweet_fields", "type": "str", "required": False, "description": "Comma list"},
            ],
            enabled=True,
            description="Users: by username",
            tab="users",
        )
        plugin.add_cmd(
            "x_user_by_id",
            instruction="Lookup user by ID.",
            params=[
                {"name": "id", "type": "str", "required": True, "description": "User ID"},
                {"name": "user_fields", "type": "str", "required": False, "description": "Comma list"},
            ],
            enabled=True,
            description="Users: by id",
            tab="users",
        )

        # Timelines / Search
        plugin.add_cmd(
            "x_user_tweets",
            instruction="User Tweet timeline.",
            params=[
                {"name": "id", "type": "str", "required": True, "description": "User ID"},
                {"name": "max_results", "type": "int", "required": False, "description": "5..100 (default 20)"},
                {"name": "since_id", "type": "str", "required": False, "description": "Since id"},
                {"name": "until_id", "type": "str", "required": False, "description": "Until id"},
                {"name": "exclude", "type": "list", "required": False, "description": "['replies','retweets']"},
                {"name": "tweet_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "expansions", "type": "str", "required": False, "description": "Comma list"},
                {"name": "media_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "pagination_token", "type": "str", "required": False, "description": "For next page"},
            ],
            enabled=True,
            description="Timeline: user tweets",
            tab="tweets",
        )
        plugin.add_cmd(
            "x_search_recent",
            instruction="Recent search (last 7 days).",
            params=[
                {"name": "query", "type": "str", "required": True, "description": "Query string with operators"},
                {"name": "max_results", "type": "int", "required": False, "description": "10..100 (default 25)"},
                {"name": "since_id", "type": "str", "required": False, "description": "Since id"},
                {"name": "until_id", "type": "str", "required": False, "description": "Until id"},
                {"name": "start_time", "type": "str", "required": False, "description": "RFC3339"},
                {"name": "end_time", "type": "str", "required": False, "description": "RFC3339"},
                {"name": "tweet_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "expansions", "type": "str", "required": False, "description": "Comma list"},
                {"name": "media_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "next_token", "type": "str", "required": False, "description": "For next page"},
            ],
            enabled=True,
            description="Search: recent",
            tab="search",
        )

        # Tweet CRUD
        plugin.add_cmd(
            "x_tweet_create",
            instruction="Create a Tweet/Post.",
            params=[
                {"name": "text", "type": "str", "required": False, "description": "Tweet text"},
                {"name": "media_ids", "type": "list", "required": False, "description": "Uploaded media ids"},
                {"name": "tagged_user_ids", "type": "list", "required": False, "description": "User IDs to tag"},
                {"name": "quote_tweet_id", "type": "str", "required": False, "description": "Quote tweet id"},
                {"name": "in_reply_to_tweet_id", "type": "str", "required": False, "description": "Reply to id"},
                {"name": "exclude_reply_user_ids", "type": "list", "required": False, "description": "Exclude ids"},
                {"name": "reply_settings", "type": "str", "required": False, "description": "everyone|following|mentionedUsers"},
                {"name": "place_id", "type": "str", "required": False, "description": "Geo place id"},
                {"name": "poll", "type": "dict", "required": False, "description": "duration_minutes, options"},
                {"name": "card_uri", "type": "str", "required": False, "description": "Card URI"},
            ],
            enabled=True,
            description="Tweets: create",
            tab="tweets",
        )
        plugin.add_cmd(
            "x_tweet_delete",
            instruction="Delete Tweet by ID.",
            params=[{"name": "id", "type": "str", "required": True, "description": "Tweet ID"}],
            enabled=True,
            description="Tweets: delete",
            tab="tweets",
        )
        plugin.add_cmd(
            "x_tweet_reply",
            instruction="Reply to a Tweet.",
            params=[
                {"name": "in_reply_to_tweet_id", "type": "str", "required": True, "description": "Parent tweet id"},
                {"name": "text", "type": "str", "required": False, "description": "Reply text"},
                {"name": "media_ids", "type": "list", "required": False, "description": "Media ids"},
            ],
            enabled=True,
            description="Tweets: reply",
            tab="tweets",
        )
        plugin.add_cmd(
            "x_tweet_quote",
            instruction="Quote a Tweet.",
            params=[
                {"name": "quote_tweet_id", "type": "str", "required": True, "description": "Quoted tweet id"},
                {"name": "text", "type": "str", "required": False, "description": "Quote text"},
                {"name": "media_ids", "type": "list", "required": False, "description": "Media ids"},
            ],
            enabled=True,
            description="Tweets: quote",
            tab="tweets",
        )

        # Actions
        plugin.add_cmd(
            "x_like",
            instruction="Like a Tweet.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Actions: like",
            tab="actions",
        )
        plugin.add_cmd(
            "x_unlike",
            instruction="Unlike a Tweet.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Actions: unlike",
            tab="actions",
        )
        plugin.add_cmd(
            "x_retweet",
            instruction="Retweet.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Actions: retweet",
            tab="actions",
        )
        plugin.add_cmd(
            "x_unretweet",
            instruction="Undo retweet.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Original tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Actions: unretweet",
            tab="actions",
        )
        plugin.add_cmd(
            "x_hide_reply",
            instruction="Hide or unhide a reply to your Tweet.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Reply tweet id"},
                {"name": "hidden", "type": "bool", "required": False, "description": "Default true"},
            ],
            enabled=True,
            description="Actions: hide/unhide reply",
            tab="actions",
        )

        # Bookmarks
        plugin.add_cmd(
            "x_bookmarks_list",
            instruction="List my bookmarks.",
            params=[
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
                {"name": "max_results", "type": "int", "required": False, "description": "Default 50"},
                {"name": "pagination_token", "type": "str", "required": False, "description": "Next page token"},
                {"name": "tweet_fields", "type": "str", "required": False, "description": "Comma list"},
                {"name": "expansions", "type": "str", "required": False, "description": "Comma list"},
                {"name": "media_fields", "type": "str", "required": False, "description": "Comma list"},
            ],
            enabled=True,
            description="Bookmarks: list",
            tab="bookmarks",
        )
        plugin.add_cmd(
            "x_bookmark_add",
            instruction="Add bookmark.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Bookmarks: add",
            tab="bookmarks",
        )
        plugin.add_cmd(
            "x_bookmark_remove",
            instruction="Remove bookmark.",
            params=[
                {"name": "tweet_id", "type": "str", "required": True, "description": "Tweet id"},
                {"name": "user_id", "type": "str", "required": False, "description": "Defaults to me"},
            ],
            enabled=True,
            description="Bookmarks: remove",
            tab="bookmarks",
        )

        # Media
        plugin.add_cmd(
            "x_upload_media",
            instruction="Upload media (INIT/APPEND/FINALIZE). Returns media_id.",
            params=[
                {"name": "path", "type": "str", "required": True, "description": "Local file path"},
                {"name": "media_type", "type": "str", "required": False, "description": "Mime, auto-guessed"},
                {"name": "media_category", "type": "str", "required": False, "description": "tweet_image|tweet_video|tweet_gif"},
                {"name": "chunk_size", "type": "int", "required": False, "description": "Bytes, default 1MB"},
                {"name": "wait_for_processing", "type": "bool", "required": False, "description": "Poll STATUS if needed"},
            ],
            enabled=True,
            description="Media: upload",
            tab="media",
        )
        plugin.add_cmd(
            "x_media_set_alt_text",
            instruction="Attach alt text (accessibility) to uploaded media.",
            params=[
                {"name": "media_id", "type": "str", "required": True, "description": "Media id from upload"},
                {"name": "alt_text", "type": "str", "required": True, "description": "Up to 1000 chars"},
            ],
            enabled=True,
            description="Media: set alt text",
            tab="media",
        )