from typing import Any
from linkedin_api import Linkedin
from ..key_handler import KeyHandler
from ..form_elements import ListElement, ButtonElement
from ..dialog import Dialog
from ..subdialogs import Applet
from ..framework import beep


class LinkedinDialog(Applet, Dialog):  # type: ignore[misc]
    """LinkedIn integration applet for managing invitations and connections.

    Provides functionality for:
    - Viewing pending connection invitations
    - Accepting or rejecting invitations
    - Viewing shared connections with inviters
    """

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        self.handlers: dict[str, Any] = {
            'profile': None,
            'connections': None,
            'invitations': self.handle_invitations,
            'messages': None,
            'notifications': None
        }
        filler = [key for key in self.handlers]
        # Extract and remove filler from kwargs to avoid duplicate keyword argument
        # Use passed-in filler if present, otherwise use handlers keys
        filler = kwargs.pop('filler', filler)
        super().__init__(*args, filler=filler, **kwargs)  # type: ignore[misc]
        self.api: Linkedin = Linkedin("chrisjmairs@gmail.com", "cm39111193")
        self.pending_invitations: list[dict[str, Any]] = []

    def ok(self, modified_name: str) -> None:
        """Handler for Return key called by Dialog.ok_wrapper.

        Invokes the handler for the category defined by the current element.

        Args:
            modified_name: Modified key name from KeyHandler.
        """
        category = self.current().value
        handler = self.handlers.get(category)
        if not handler:
            self.say_strings(f"no handler available for {category}")
        else:
            result = handler()
            self.say_current() if not result else self.say_strings(result)

    def handle_invitations(self) -> None:
        """Fetch and display pending LinkedIn invitations.

        Retrieves up to 30 pending invitations and displays them in a dialog
        with accept/reject buttons. Shows shared connections for each inviter.
        """
        # Fetch pending invitations
        self.say_strings('getting up to 30 most recent pending invitations')
        self.pending_invitations = self.api.get_invitations(limit=30)
        pending_count = f"{len(self.pending_invitations)} pending invitations"
        invites: list[str] = []
        for invite in self.pending_invitations:
            # Extract details about the inviter
            beep()
            inviter = invite.get("fromMember", {})
            first_name = inviter.get("firstName", "No first name")
            last_name = inviter.get("lastName", "No last name")
            #occupation = inviter.get("occupation", "No occupation")
            message = inviter.get("message", "")
            shared_conns = self.api.get_profile_connections(inviter['entityUrn'].split(':')[-1])
            num = len(shared_conns)
            first_5 = ', '.join([c['name'] for c in shared_conns if c.get('name')][:5])
            shared = f"{num} shared connections including {first_5}"
            details = ', '.join([first_name, last_name, shared])
            details = details if not len(message) else ', '.join([details, message])
            invites.append(details)
        if not len(invites):
            self.say_strings('no pending invitations')
        else:
            fields = [
                (ListElement, 'invitations', None, invites),
                (ButtonElement, {'name': 'accept', 'on_press': self.on_press}),
                (ButtonElement, {'name': 'reject', 'on_press': self.on_press}),
            ]
            self.input_values(title=pending_count, fields=fields, say_labels=False)
            self.say_current()
            return

    def on_press(self, button: ButtonElement) -> None:
        """Handle accept/reject button press for invitations.

        Args:
            button: The ButtonElement that was pressed (accept or reject).
        """
        action = button.name  # 'accept' or 'reject'
        index = self.child.invitations.index  # type: ignore[attr-defined]
        invitation = self.pending_invitations[index]
        result = self.api.reply_invitation(invitation['ern'], invitation['secret'], action)
        self.say_strings(f"{action}ed {self.child.invitations.value}")  # type: ignore[attr-defined]
        #now need to remove from list element and pending_invitations and refill list element

    def garbage(self) -> None:  # type: ignore[misc]  # Dead code - undefined variables things, first_name, last_name, headline, api
        """Legacy invitation processing code (not currently used)."""
        things: list[dict[str, Any]] = []  # Undefined - was parameter in original code
        for invite in things:
            shared_connections = invite.get("sharedConnections", [])
            shared_count = len(shared_connections)
            shared_names = [conn.get("name", "Unknown") for conn in shared_connections[:5]]
            # Display information to the user
            first_name = invite.get("firstName", "")
            last_name = invite.get("lastName", "")
            headline = invite.get("headline", "")
            print(f"\nInvitation from {first_name} {last_name}")
            print(f"Headline: {headline}")
            print(f"Shared Connections: {shared_count}")
            if shared_count > 0:
                print(f"First 5 Shared Connections: {', '.join(shared_names)}")
            # Prompt user to accept or reject
            while True:
                action = input("Would you like to quit (q), accept this invitation (a) or reject (r) this invitation? (a/r): ").strip().lower()
                if action in ['q','a', 'r']:
                    break
                print("Invalid input. Please enter 'a' to accept or 'r' to reject.")
            # Perform the appropriate action
            if action=='q':
                print('abandoned processing invitations')
                break
            elif action == 'a':
                self.api.accept_invitation(invite['id'])
                print("Invitation accepted.")
            else:
                self.api.reject_invitation(invite['id'])
                print("Invitation rejected.")