"""
Repository selection screen for KITECH TUI.

This screen displays a list of accessible repositories and allows the user
to select one for file management operations.
"""

from textual.app import ComposeResult
from textual.containers import Container, Vertical
from textual.screen import Screen
from textual.widgets import DataTable, Footer, Header, LoadingIndicator, Static

from kitech_repository.core.client import KitechClient
from kitech_repository.core.exceptions import ApiError, AuthenticationError
from kitech_repository.tui.messages import RepositorySelected


class RepositorySelectionScreen(Screen):
    """
    Screen for selecting a repository from the user's accessible repositories.

    Features:
    - Loads repository list from API on mount
    - Displays repositories in a DataTable with 리포지토리 이름, 소유자, 내 권한, 설명 columns
    - Allows selection with Enter key
    - Supports refresh with F5
    - Handles empty list and error states
    """

    BINDINGS = [
        ("f5", "refresh", "새로고침"),
        ("escape", "quit_app", "나가기"),
    ]

    CSS = """
    RepositorySelectionScreen {
        align: center middle;
    }

    #repository-table {
        width: 80%;
        height: 70%;
        margin: 2 4;
    }

    #empty-message, #error-message {
        width: 80%;
        height: auto;
        margin: 2 4;
        text-align: center;
    }

    #loading-container {
        width: 80%;
        height: auto;
        margin: 2 4;
        align: center middle;
    }

    #loading-message {
        text-align: center;
        color: yellow;
        margin: 1 0;
    }

    LoadingIndicator {
        height: auto;
        margin: 1 0;
    }
    """

    def __init__(self, client: KitechClient, **kwargs):
        """
        Initialize the repository selection screen.

        Args:
            client: KitechClient instance for API calls
            **kwargs: Additional arguments passed to Screen
        """
        super().__init__(**kwargs)
        self.client = client
        self._repositories = []
        self._loading = False

    def compose(self) -> ComposeResult:
        """Compose the repository selection screen UI."""
        yield Header()
        yield Container(id="content-container")
        yield Footer()

    async def on_mount(self) -> None:
        """Load repositories from API when screen mounts."""
        await self._load_repositories()

    async def _load_repositories(self) -> None:
        """
        Load repository list from API and populate the DataTable.

        Handles success, empty list, and error cases with loading indicators
        and actionable error messages (T062, T064).
        """
        self._loading = True
        container = self.query_one("#content-container", Container)

        # Clear existing content
        await container.remove_children()

        # Show loading indicator with message (T062)
        loading_container = Vertical(id="loading-container")
        await container.mount(loading_container)
        await loading_container.mount(LoadingIndicator())
        await loading_container.mount(Static("리포지토리 목록을 불러오는 중...", id="loading-message"))

        try:
            # Call API to get repositories (synchronous call, returns dict)
            result = self.client.list_repositories()
            repositories = result.get("repositories", [])
            self._repositories = repositories

            # Remove loading indicator
            await container.remove_children()

            if not repositories:
                # Empty state
                await container.mount(
                    Static(
                        "접근 가능한 리포지토리가 없습니다\n\n"
                        "리포지토리에 대한 접근 권한이 없습니다.\n"
                        "관리자에게 연락하여 권한을 요청해주세요.\n\n"
                        "F5 키를 눌러 새로고침하거나 Esc 키를 눌러 종료하세요.",
                        id="empty-message",
                        classes="status-warning",
                    )
                )
            else:
                # Create and populate DataTable
                table = DataTable(id="repository-table")
                table.cursor_type = "row"
                table.zebra_stripes = True

                # Add columns
                table.add_column("리포지토리 이름", key="name")
                table.add_column("소유자", key="owner")
                table.add_column("내 권한", key="role")
                table.add_column("설명", key="description")

                # 권한 한국어 매핑
                role_map = {"OWNER": "소유자", "ADMIN": "관리자", "VIEWER": "뷰어", "NONE": "없음", None: "-"}

                # Add rows
                for repo in repositories:
                    user_role = role_map.get(repo.user_role, repo.user_role or "-")
                    table.add_row(repo.name, repo.owner_name, user_role, repo.description or "-", key=str(repo.id))

                await container.mount(table)

                # Focus the table
                table.focus()

        except AuthenticationError as e:
            # Authentication error - specific actionable message (T064)
            await container.remove_children()
            await container.mount(
                Static(
                    f"Authentication Failed\n\n"
                    f"Your session may have expired or your API key is invalid.\n\n"
                    f"Error: {str(e)}\n\n"
                    f"Action: Run 'kitech-dev login' to re-authenticate.\n"
                    f"Press Escape to quit.",
                    id="error-message",
                    classes="status-error",
                )
            )
        except ApiError as e:
            # API/Network error - actionable message with retry instruction (T064)
            await container.remove_children()
            await container.mount(
                Static(
                    f"Network Error\n\n"
                    f"Failed to connect to the repository server.\n\n"
                    f"Error: {str(e)}\n\n"
                    f"Action: Check your network connection and press F5 to retry.\n"
                    f"Press Escape to quit.",
                    id="error-message",
                    classes="status-error",
                )
            )
        except Exception as e:
            # Generic error - actionable message (T064)
            await container.remove_children()
            await container.mount(
                Static(
                    f"Failed to load repositories\n\n"
                    f"An unexpected error occurred.\n\n"
                    f"Error: {str(e)}\n\n"
                    f"Action: Press F5 to retry or Escape to quit.",
                    id="error-message",
                    classes="status-error",
                )
            )

        finally:
            self._loading = False

    def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
        """
        Handle repository selection when user presses Enter on a row.

        This is called automatically by Textual when Enter is pressed on a DataTable row.

        Args:
            event: The RowSelected event from DataTable
        """
        # Row key is the repository ID (we set it as str(repo.id) when adding rows)
        try:
            repo_id = int(event.row_key.value)  # Convert RowKey to int
        except (ValueError, AttributeError):
            return

        # Find the repository by ID
        selected_repo = None
        for repo in self._repositories:
            if repo.id == repo_id:
                selected_repo = repo
                break

        if selected_repo:
            # Post RepositorySelected message with user role
            self.post_message(
                RepositorySelected(
                    repository_id=selected_repo.id,
                    repository_name=selected_repo.name,
                    user_role=selected_repo.user_role,
                )
            )

    async def action_refresh(self) -> None:
        """
        Handle refresh action (F5 key).

        Reloads the repository list from the API.
        """
        if not self._loading:
            await self._load_repositories()

    def action_quit_app(self) -> None:
        """
        Handle quit action (Escape key).

        Exits the application.
        """
        self.app.exit()
