from __future__ import annotations

from typing import Any

from .helpers import (
    action_matches_finding,
    coerce_follow_up_items,
    deduplicate_follow_up_items,
    derive_trigger_phase_from_action_type,
    derive_trigger_phase_from_key,
    ensure_dict,
    ensure_list,
    merge_metadata,
    normalize_follow_up_item,
)


def collect_review_follow_ups(
    *, review: dict[str, Any], finding: dict[str, Any]
) -> list[dict[str, Any]]:
    """Gom follow-up từ nhiều nguồn metadata."""
    items: list[dict[str, Any]] = []
    review_id = str(review.get("review_id") or "")
    finding_id = str(finding.get("finding_id") or "")
    finding_code = str(finding.get("finding_code") or "")
    metadata_keys = (
        "post_close_actions",
        "post_close_backlog",
        "close_follow_ups",
        "post_verification_actions",
        "verification_follow_ups",
        "post_verify_actions",
    )
    metadata_sources = [
        ensure_dict(review.get("metadata")),
        ensure_dict(finding.get("metadata")),
    ]
    for assignment in ensure_list(finding.get("assignments")):
        metadata_sources.append(ensure_dict(assignment.get("metadata")))
        for submission in ensure_list(assignment.get("submissions")):
            metadata_sources.append(ensure_dict(submission.get("metadata")))
            metadata_sources.append(ensure_dict(submission.get("submitted_payload")))
    for source in metadata_sources:
        for key in metadata_keys:
            for raw_item in coerce_follow_up_items(source.get(key)):
                items.append(
                    normalize_follow_up_item(
                        raw_item,
                        review_id=review_id,
                        finding_id=finding_id,
                        finding_code=finding_code,
                        trigger_phase=derive_trigger_phase_from_key(key),
                    )
                )
    for action in ensure_list(review.get("actions")):
        payload = ensure_dict(action.get("action_payload"))
        if not action_matches_finding(action_payload=payload, finding=finding):
            continue
        for key in metadata_keys:
            for raw_item in coerce_follow_up_items(payload.get(key)):
                items.append(
                    normalize_follow_up_item(
                        merge_metadata(
                            raw_item,
                            {
                                "action_id": action.get("action_id"),
                                "created_at": action.get("created_at"),
                            },
                        ),
                        review_id=review_id,
                        finding_id=finding_id,
                        finding_code=finding_code,
                        trigger_phase=derive_trigger_phase_from_key(key),
                    )
                )
        if any(
            payload.get(key) is not None
            for key in (
                "follow_up_action",
                "next_action",
                "post_action",
                "title",
                "reason",
            )
        ):
            candidate: Any = payload.get("follow_up_action")
            if candidate is None and payload.get("next_action") is not None:
                candidate = {"title": payload.get("next_action")}
            elif candidate is None and payload.get("post_action") is not None:
                candidate = {"title": payload.get("post_action")}
            elif candidate is None:
                candidate = {
                    "title": payload.get("title") or action.get("action_summary"),
                    "reason": payload.get("reason") or action.get("action_summary"),
                    "priority": payload.get("priority"),
                    "status": payload.get("status"),
                    "due_date": payload.get("due_date"),
                    "department_code": payload.get("target_department_code"),
                    "owner_employee_code": payload.get("target_employee_code"),
                }
            if not isinstance(candidate, dict):
                candidate = {"title": str(candidate)}
            items.append(
                normalize_follow_up_item(
                    merge_metadata(
                        candidate,
                        {
                            "action_id": action.get("action_id"),
                            "created_at": action.get("created_at"),
                        },
                    ),
                    review_id=review_id,
                    finding_id=finding_id,
                    finding_code=finding_code,
                    trigger_phase=derive_trigger_phase_from_action_type(
                        action.get("action_type")
                    ),
                )
            )
    return deduplicate_follow_up_items(items)
