from __future__ import annotations

import os
from typing import Any

import boto3

from applications.postcode_splitter.postcode_splitter_trigger_body import (
    PostcodeSplitterTriggerBody,
)
from infrastructure.address2uprn_queue_client import Address2UprnQueueClient
from infrastructure.csv_s3_client import CsvS3Client
from orchestration.postcode_splitter_orchestrator import PostcodeSplitterOrchestrator
from orchestration.task_orchestrator import TaskOrchestrator
from repositories.user_address.user_address_csv_s3_repository import (
    UserAddressCsvS3Repository,
)
from utilities.aws_lambda.subtask_handler import subtask_handler


@subtask_handler()
def handler(
    body: dict[str, Any], context: Any, task_orchestrator: TaskOrchestrator
) -> dict[str, list[str]]:
    trigger = PostcodeSplitterTriggerBody.model_validate(body)

    bucket = os.environ["S3_BUCKET_NAME"]
    queue_url = os.environ["ADDRESS2UPRN_QUEUE_URL"]

    # boto3.client is overloaded per-service in the installed stubs; cast
    # to Any so the strict-mode checker treats it as opaque.
    boto3_client: Any = boto3.client  # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
    boto_s3: Any = boto3_client("s3")
    boto_sqs: Any = boto3_client("sqs")

    csv_client = CsvS3Client(boto_s3, bucket)
    user_address_repo = UserAddressCsvS3Repository(csv_client, bucket)
    queue_client = Address2UprnQueueClient(boto_sqs, queue_url)

    splitter = PostcodeSplitterOrchestrator(
        task_orchestrator=task_orchestrator,
        user_address_repo=user_address_repo,
        queue_client=queue_client,
    )

    child_ids = splitter.split_and_dispatch(
        parent_task_id=trigger.task_id,
        parent_subtask_id=trigger.sub_task_id,
        input_s3_uri=trigger.s3_uri,
    )

    return {"child_subtask_ids": [str(cid) for cid in child_ids]}
