"""Repair flow for imap email content integration."""

from typing import Any

import voluptuous as vol
import yaml

from homeassistant import data_entry_flow
from homeassistant.components.imap import DOMAIN as IMAP_DOMAIN
from homeassistant.components.repairs import RepairsFlow
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import (
    CONF_NAME,
    CONF_PASSWORD,
    CONF_PORT,
    CONF_USERNAME,
    CONF_VALUE_TEMPLATE,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.typing import ConfigType

from .const import CONF_FOLDER, CONF_SENDERS, CONF_SERVER, DOMAIN


async def async_process_issue(hass: HomeAssistant, config: ConfigType) -> None:
    """Register an issue and suggest new config."""

    name: str = config.get(CONF_NAME) or config[CONF_USERNAME]

    issue_id = (
        f"{name}_{config[CONF_USERNAME]}_{config[CONF_SERVER]}_{config[CONF_FOLDER]}"
    )

    if CONF_VALUE_TEMPLATE in config:
        template: str = config[CONF_VALUE_TEMPLATE].template
        template = template.replace("subject", 'trigger.event.data["subject"]')
        template = template.replace("from", 'trigger.event.data["sender"]')
        template = template.replace("date", 'trigger.event.data["date"]')
        template = template.replace("body", 'trigger.event.data["text"]')
    else:
        template = '{{ trigger.event.data["subject"] }}'

    template_sensor_config: ConfigType = {
        "template": [
            {
                "trigger": [
                    {
                        "id": "custom_event",
                        "platform": "event",
                        "event_type": "imap_content",
                        "event_data": {"sender": config[CONF_SENDERS][0]},
                    }
                ],
                "sensor": [
                    {
                        "state": template,
                        "name": name,
                    }
                ],
            }
        ]
    }

    data = {
        CONF_SERVER: config[CONF_SERVER],
        CONF_PORT: config[CONF_PORT],
        CONF_USERNAME: config[CONF_USERNAME],
        CONF_PASSWORD: config[CONF_PASSWORD],
        CONF_FOLDER: config[CONF_FOLDER],
    }
    data[CONF_VALUE_TEMPLATE] = template
    data[CONF_NAME] = name
    placeholders = {"yaml_example": yaml.dump(template_sensor_config)}
    placeholders.update(data)

    ir.async_create_issue(
        hass,
        DOMAIN,
        issue_id,
        breaks_in_ha_version="2023.10.0",
        is_fixable=True,
        severity=ir.IssueSeverity.WARNING,
        translation_key="migration",
        translation_placeholders=placeholders,
        data=data,
    )


class DeprecationRepairFlow(RepairsFlow):
    """Handler for an issue fixing flow."""

    def __init__(self, issue_id: str, config: ConfigType) -> None:
        """Create flow."""
        self._name: str = config[CONF_NAME]
        self._config: dict[str, Any] = config
        self._issue_id = issue_id
        super().__init__()

    async def async_step_init(
        self, user_input: dict[str, str] | None = None
    ) -> data_entry_flow.FlowResult:
        """Handle the first step of a fix flow."""
        return await self.async_step_start()

    @callback
    def _async_get_placeholders(self) -> dict[str, str] | None:
        issue_registry = ir.async_get(self.hass)
        description_placeholders = None
        if issue := issue_registry.async_get_issue(self.handler, self.issue_id):
            description_placeholders = issue.translation_placeholders

        return description_placeholders

    async def async_step_start(
        self, user_input: dict[str, str] | None = None
    ) -> data_entry_flow.FlowResult:
        """Wait for the user to start the config migration."""
        placeholders = self._async_get_placeholders()
        if user_input is None:
            return self.async_show_form(
                step_id="start",
                data_schema=vol.Schema({}),
                description_placeholders=placeholders,
            )

        return await self.async_step_confirm()

    async def async_step_confirm(
        self, user_input: dict[str, str] | None = None
    ) -> data_entry_flow.FlowResult:
        """Handle the confirm step of a fix flow."""
        placeholders = self._async_get_placeholders()
        if user_input is not None:
            user_input[CONF_NAME] = self._name
            result = await self.hass.config_entries.flow.async_init(
                IMAP_DOMAIN, context={"source": SOURCE_IMPORT}, data=self._config
            )
            if result["type"] == FlowResultType.ABORT:
                ir.async_delete_issue(self.hass, DOMAIN, self._issue_id)
                ir.async_create_issue(
                    self.hass,
                    DOMAIN,
                    self._issue_id,
                    breaks_in_ha_version="2023.10.0",
                    is_fixable=False,
                    severity=ir.IssueSeverity.WARNING,
                    translation_key="deprecation",
                    translation_placeholders=placeholders,
                    data=self._config,
                    learn_more_url="https://www.home-assistant.io/integrations/imap/#using-events",
                )
                return self.async_abort(reason=result["reason"])
            return self.async_create_entry(
                title="",
                data={},
            )

        return self.async_show_form(
            step_id="confirm",
            data_schema=vol.Schema({}),
            description_placeholders=placeholders,
        )


async def async_create_fix_flow(
    hass: HomeAssistant,
    issue_id: str,
    data: dict[str, str | int | float | None],
) -> RepairsFlow:
    """Create flow."""
    return DeprecationRepairFlow(issue_id, data)
