"""Config flow for Ghost integration."""

from collections.abc import Mapping
import logging
from typing import Any, override

from aioghost import GhostAdminAPI
from aioghost.exceptions import GhostAuthError, GhostError
import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .const import CONF_ADMIN_API_KEY, CONF_API_URL, DOMAIN

_LOGGER = logging.getLogger(__name__)

GHOST_INTEGRATION_SETUP_URL = "https://account.ghost.org/?r=settings/integrations/new"

STEP_USER_DATA_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_API_URL): str,
        vol.Required(CONF_ADMIN_API_KEY): str,
    }
)

STEP_REAUTH_DATA_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_ADMIN_API_KEY): str,
    }
)


class GhostConfigFlow(ConfigFlow, domain=DOMAIN):
    """Handle a config flow for Ghost."""

    VERSION = 1

    async def async_step_reauth(
        self, entry_data: Mapping[str, Any]
    ) -> ConfigFlowResult:
        """Handle reauthentication."""
        return await self.async_step_reauth_confirm()

    async def async_step_reauth_confirm(
        self, user_input: dict[str, Any] | None = None
    ) -> ConfigFlowResult:
        """Handle reauth confirmation."""
        reauth_entry = self._get_reauth_entry()
        errors: dict[str, str] = {}

        if user_input is not None:
            admin_api_key = user_input[CONF_ADMIN_API_KEY]

            if ":" not in admin_api_key:
                errors["base"] = "invalid_api_key"
            else:
                try:
                    await self._validate_credentials(
                        reauth_entry.data[CONF_API_URL], admin_api_key
                    )
                except GhostAuthError:
                    errors["base"] = "invalid_auth"
                except GhostError:
                    errors["base"] = "cannot_connect"
                except Exception:
                    _LOGGER.exception("Unexpected error during Ghost reauth")
                    errors["base"] = "unknown"
                else:
                    return self.async_update_reload_and_abort(
                        reauth_entry,
                        data_updates=user_input,
                    )

        return self.async_show_form(
            step_id="reauth_confirm",
            data_schema=STEP_REAUTH_DATA_SCHEMA,
            errors=errors,
            description_placeholders={
                "title": reauth_entry.title,
                "setup_url": GHOST_INTEGRATION_SETUP_URL,
            },
        )

    @override
    async def async_step_user(
        self, user_input: dict[str, Any] | None = None
    ) -> ConfigFlowResult:
        """Handle the initial step."""
        errors: dict[str, str] = {}

        if user_input is not None:
            api_url = user_input[CONF_API_URL].rstrip("/")
            admin_api_key = user_input[CONF_ADMIN_API_KEY]

            if ":" not in admin_api_key:
                errors["base"] = "invalid_api_key"
            else:
                result = await self._validate_and_create(api_url, admin_api_key, errors)
                if result:
                    return result

        return self.async_show_form(
            step_id="user",
            data_schema=STEP_USER_DATA_SCHEMA,
            errors=errors,
            description_placeholders={"setup_url": GHOST_INTEGRATION_SETUP_URL},
        )

    async def async_step_reconfigure(
        self, user_input: dict[str, Any] | None = None
    ) -> ConfigFlowResult:
        """Handle reconfiguration."""
        reconfigure_entry = self._get_reconfigure_entry()
        errors: dict[str, str] = {}

        if user_input is not None:
            api_url = user_input[CONF_API_URL].rstrip("/")
            admin_api_key = user_input[CONF_ADMIN_API_KEY]

            if ":" not in admin_api_key:
                errors["base"] = "invalid_api_key"
            else:
                try:
                    site = await self._validate_credentials(api_url, admin_api_key)
                except GhostAuthError:
                    errors["base"] = "invalid_auth"
                except GhostError:
                    errors["base"] = "cannot_connect"
                except Exception:
                    _LOGGER.exception("Unexpected error during Ghost reconfigure")
                    errors["base"] = "unknown"
                else:
                    await self.async_set_unique_id(site["site_uuid"])
                    self._abort_if_unique_id_mismatch()
                    return self.async_update_reload_and_abort(
                        reconfigure_entry,
                        data_updates={
                            CONF_API_URL: api_url,
                            CONF_ADMIN_API_KEY: admin_api_key,
                        },
                    )

        return self.async_show_form(
            step_id="reconfigure",
            data_schema=self.add_suggested_values_to_schema(
                data_schema=STEP_USER_DATA_SCHEMA,
                suggested_values=user_input or reconfigure_entry.data,
            ),
            errors=errors,
            description_placeholders={"setup_url": GHOST_INTEGRATION_SETUP_URL},
        )

    async def _validate_credentials(
        self, api_url: str, admin_api_key: str
    ) -> dict[str, Any]:
        """Validate credentials against the Ghost API.

        Returns site data on success. Raises GhostAuthError or GhostError on failure.
        """
        api = GhostAdminAPI(
            api_url, admin_api_key, session=async_get_clientsession(self.hass)
        )
        return await api.get_site()

    async def _validate_and_create(
        self,
        api_url: str,
        admin_api_key: str,
        errors: dict[str, str],
    ) -> ConfigFlowResult | None:
        """Validate credentials and create entry."""
        try:
            site = await self._validate_credentials(api_url, admin_api_key)
        except GhostAuthError:
            errors["base"] = "invalid_auth"
            return None
        except GhostError:
            errors["base"] = "cannot_connect"
            return None
        except Exception:
            _LOGGER.exception("Unexpected error during Ghost setup")
            errors["base"] = "unknown"
            return None

        site_title = site["title"]

        await self.async_set_unique_id(site["site_uuid"])
        self._abort_if_unique_id_configured()

        return self.async_create_entry(
            title=site_title,
            data={
                CONF_API_URL: api_url,
                CONF_ADMIN_API_KEY: admin_api_key,
            },
        )
