from typing import List

from . import field

METRICS_SCHEMA = {
    "metrics.absolute_top_impression_percentage": "DOUBLE",
    "metrics.active_view_cpm": "DOUBLE",
    "metrics.active_view_ctr": "DOUBLE",
    "metrics.active_view_impressions": "INT64",
    "metrics.active_view_measurability": "DOUBLE",
    "metrics.active_view_measurable_cost_micros": "INT64",
    "metrics.active_view_measurable_impressions": "INT64",
    "metrics.active_view_viewability": "DOUBLE",
    "metrics.all_conversions": "DOUBLE",
    "metrics.all_conversions_by_conversion_date": "DOUBLE",
    "metrics.all_conversions_from_click_to_call": "DOUBLE",
    "metrics.all_conversions_from_directions": "DOUBLE",
    "metrics.all_conversions_from_interactions_rate": "DOUBLE",
    "metrics.all_conversions_from_interactions_value_per_interaction": "DOUBLE",
    "metrics.all_conversions_from_location_asset_click_to_call": "DOUBLE",
    "metrics.all_conversions_from_location_asset_directions": "DOUBLE",
    "metrics.all_conversions_from_location_asset_menu": "DOUBLE",
    "metrics.all_conversions_from_location_asset_order": "DOUBLE",
    "metrics.all_conversions_from_location_asset_other_engagement": "DOUBLE",
    "metrics.all_conversions_from_location_asset_store_visits": "DOUBLE",
    "metrics.all_conversions_from_location_asset_website": "DOUBLE",
    "metrics.all_conversions_from_menu": "DOUBLE",
    "metrics.all_conversions_from_order": "DOUBLE",
    "metrics.all_conversions_from_other_engagement": "DOUBLE",
    "metrics.all_conversions_from_store_visit": "DOUBLE",
    "metrics.all_conversions_from_store_website": "DOUBLE",
    "metrics.all_conversions_value": "DOUBLE",
    "metrics.all_conversions_value_by_conversion_date": "DOUBLE",
    "metrics.all_conversions_value_per_cost": "DOUBLE",
    "metrics.all_new_customer_lifetime_value": "DOUBLE",
    "metrics.asset_best_performance_cost_percentage": "DOUBLE",
    "metrics.asset_best_performance_impression_percentage": "DOUBLE",
    "metrics.asset_good_performance_cost_percentage": "DOUBLE",
    "metrics.asset_good_performance_impression_percentage": "DOUBLE",
    "metrics.asset_learning_performance_cost_percentage": "DOUBLE",
    "metrics.asset_learning_performance_impression_percentage": "DOUBLE",
    "metrics.asset_low_performance_cost_percentage": "DOUBLE",
    "metrics.asset_low_performance_impression_percentage": "DOUBLE",
    "metrics.asset_pinned_as_description_position_one_count": "INT64",
    "metrics.asset_pinned_as_description_position_two_count": "INT64",
    "metrics.asset_pinned_as_headline_position_one_count": "INT64",
    "metrics.asset_pinned_as_headline_position_three_count": "INT64",
    "metrics.asset_pinned_as_headline_position_two_count": "INT64",
    "metrics.asset_pinned_total_count": "INT64",
    "metrics.asset_unrated_performance_cost_percentage": "DOUBLE",
    "metrics.asset_unrated_performance_impression_percentage": "DOUBLE",
    "metrics.auction_insight_search_absolute_top_impression_percentage": "DOUBLE",
    "metrics.auction_insight_search_impression_share": "DOUBLE",
    "metrics.auction_insight_search_outranking_share": "DOUBLE",
    "metrics.auction_insight_search_overlap_rate": "DOUBLE",
    "metrics.auction_insight_search_position_above_rate": "DOUBLE",
    "metrics.auction_insight_search_top_impression_percentage": "DOUBLE",
    "metrics.average_cart_size": "DOUBLE",
    "metrics.average_cost": "DOUBLE",
    "metrics.average_cpc": "DOUBLE",
    "metrics.average_cpe": "DOUBLE",
    "metrics.average_cpm": "DOUBLE",
    "metrics.average_cpv": "DOUBLE",
    "metrics.average_impression_frequency_per_user": "DOUBLE",
    "metrics.average_order_value_micros": "INT64",
    "metrics.average_page_views": "DOUBLE",
    "metrics.average_target_cpa_micros": "INT64",
    "metrics.average_target_roas": "DOUBLE",
    "metrics.average_time_on_site": "DOUBLE",
    "metrics.benchmark_average_max_cpc": "DOUBLE",
    "metrics.benchmark_ctr": "DOUBLE",
    "metrics.biddable_app_install_conversions": "DOUBLE",
    "metrics.biddable_app_post_install_conversions": "DOUBLE",
    "metrics.bounce_rate": "DOUBLE",
    "metrics.clicks": "INT64",
    "metrics.combined_clicks": "INT64",
    "metrics.combined_clicks_per_query": "DOUBLE",
    "metrics.combined_queries": "INT64",
    "metrics.content_budget_lost_impression_share": "DOUBLE",
    "metrics.content_impression_share": "DOUBLE",
    "metrics.content_rank_lost_impression_share": "DOUBLE",
    "metrics.conversion_last_conversion_date": "DATE",
    "metrics.conversion_last_received_request_date_time": "DATE",
    "metrics.conversions": "DOUBLE",
    "metrics.conversions_by_conversion_date": "DOUBLE",
    "metrics.conversions_from_interactions_rate": "DOUBLE",
    "metrics.conversions_from_interactions_value_per_interaction": "DOUBLE",
    "metrics.conversions_value": "DOUBLE",
    "metrics.conversions_value_by_conversion_date": "DOUBLE",
    "metrics.conversions_value_per_cost": "DOUBLE",
    "metrics.cost_micros": "INT64",
    "metrics.cost_of_goods_sold_micros": "INT64",
    "metrics.cost_per_all_conversions": "DOUBLE",
    "metrics.cost_per_conversion": "DOUBLE",
    "metrics.cost_per_current_model_attributed_conversion": "DOUBLE",
    "metrics.cross_device_conversions": "DOUBLE",
    "metrics.cross_device_conversions_value_micros": "INT64",
    "metrics.cross_sell_cost_of_goods_sold_micros": "INT64",
    "metrics.cross_sell_gross_profit_micros": "INT64",
    "metrics.cross_sell_revenue_micros": "INT64",
    "metrics.cross_sell_units_sold": "DOUBLE",
    "metrics.ctr": "DOUBLE",
    "metrics.current_model_attributed_conversions": "DOUBLE",
    "metrics.current_model_attributed_conversions_from_interactions_rate": "DOUBLE",
    "metrics.current_model_attributed_conversions_from_interactions_value_per_interaction": "DOUBLE",
    "metrics.current_model_attributed_conversions_value": "DOUBLE",
    "metrics.current_model_attributed_conversions_value_per_cost": "DOUBLE",
    "metrics.eligible_impressions_from_location_asset_store_reach": "INT64",
    "metrics.engagement_rate": "DOUBLE",
    "metrics.engagements": "INT64",
    "metrics.general_invalid_click_rate": "DOUBLE",
    "metrics.general_invalid_clicks": "INT64",
    "metrics.gmail_forwards": "INT64",
    "metrics.gmail_saves": "INT64",
    "metrics.gmail_secondary_clicks": "INT64",
    "metrics.gross_profit_margin": "DOUBLE",
    "metrics.gross_profit_micros": "INT64",
    "metrics.historical_creative_quality_score": "ENUM",
    "metrics.historical_landing_page_quality_score": "ENUM",
    "metrics.historical_quality_score": "INT64",
    "metrics.historical_search_predicted_ctr": "ENUM",
    "metrics.hotel_average_lead_value_micros": "DOUBLE",
    "metrics.hotel_commission_rate_micros": "INT64",
    "metrics.hotel_eligible_impressions": "INT64",
    "metrics.hotel_expected_commission_cost": "DOUBLE",
    "metrics.hotel_price_difference_percentage": "DOUBLE",
    "metrics.impressions": "INT64",
    "metrics.impressions_from_store_reach": "INT64",
    "metrics.interaction_event_types": "ENUM",
    "metrics.interaction_rate": "DOUBLE",
    "metrics.interactions": "INT64",
    "metrics.invalid_click_rate": "DOUBLE",
    "metrics.invalid_clicks": "INT64",
    "metrics.lead_cost_of_goods_sold_micros": "INT64",
    "metrics.lead_gross_profit_micros": "INT64",
    "metrics.lead_revenue_micros": "INT64",
    "metrics.lead_units_sold": "DOUBLE",
    "metrics.linked_entities_count": "INT64",
    "metrics.linked_sample_entities": "STRING",
    "metrics.message_chat_rate": "DOUBLE",
    "metrics.message_chats": "INT64",
    "metrics.message_impressions": "INT64",
    "metrics.mobile_friendly_clicks_percentage": "DOUBLE",
    "metrics.new_customer_lifetime_value": "DOUBLE",
    "metrics.optimization_score_uplift": "DOUBLE",
    "metrics.optimization_score_url": "STRING",
    "metrics.orders": "DOUBLE",
    "metrics.organic_clicks": "INT64",
    "metrics.organic_clicks_per_query": "DOUBLE",
    "metrics.organic_impressions": "INT64",
    "metrics.organic_impressions_per_query": "DOUBLE",
    "metrics.organic_queries": "INT64",
    "metrics.percent_new_visitors": "DOUBLE",
    "metrics.phone_calls": "INT64",
    "metrics.phone_impressions": "INT64",
    "metrics.phone_through_rate": "DOUBLE",
    "metrics.publisher_organic_clicks": "INT64",
    "metrics.publisher_purchased_clicks": "INT64",
    "metrics.publisher_unknown_clicks": "INT64",
    "metrics.relative_ctr": "DOUBLE",
    "metrics.results_conversions_purchase": "DOUBLE",
    "metrics.revenue_micros": "INT64",
    "metrics.sample_best_performance_entities": "STRING",
    "metrics.sample_good_performance_entities": "STRING",
    "metrics.sample_learning_performance_entities": "STRING",
    "metrics.sample_low_performance_entities": "STRING",
    "metrics.sample_unrated_performance_entities": "STRING",
    "metrics.search_absolute_top_impression_share": "DOUBLE",
    "metrics.search_budget_lost_absolute_top_impression_share": "DOUBLE",
    "metrics.search_budget_lost_impression_share": "DOUBLE",
    "metrics.search_budget_lost_top_impression_share": "DOUBLE",
    "metrics.search_click_share": "DOUBLE",
    "metrics.search_exact_match_impression_share": "DOUBLE",
    "metrics.search_impression_share": "DOUBLE",
    "metrics.search_rank_lost_absolute_top_impression_share": "DOUBLE",
    "metrics.search_rank_lost_impression_share": "DOUBLE",
    "metrics.search_rank_lost_top_impression_share": "DOUBLE",
    "metrics.search_top_impression_share": "DOUBLE",
    "metrics.search_volume": "MESSAGE",
    "metrics.sk_ad_network_installs": "INT64",
    "metrics.sk_ad_network_total_conversions": "INT64",
    "metrics.speed_score": "INT64",
    "metrics.store_visits_last_click_model_attributed_conversions": "DOUBLE",
    "metrics.top_impression_percentage": "DOUBLE",
    "metrics.unique_users": "INT64",
    "metrics.units_sold": "DOUBLE",
    "metrics.valid_accelerated_mobile_pages_clicks_percentage": "DOUBLE",
    "metrics.value_per_all_conversions": "DOUBLE",
    "metrics.value_per_all_conversions_by_conversion_date": "DOUBLE",
    "metrics.value_per_conversion": "DOUBLE",
    "metrics.value_per_conversions_by_conversion_date": "DOUBLE",
    "metrics.value_per_current_model_attributed_conversion": "DOUBLE",
    "metrics.video_quartile_p100_rate": "DOUBLE",
    "metrics.video_quartile_p25_rate": "DOUBLE",
    "metrics.video_quartile_p50_rate": "DOUBLE",
    "metrics.video_quartile_p75_rate": "DOUBLE",
    "metrics.video_view_rate": "DOUBLE",
    "metrics.video_view_rate_in_feed": "DOUBLE",
    "metrics.video_view_rate_in_stream": "DOUBLE",
    "metrics.video_view_rate_shorts": "DOUBLE",
    "metrics.video_views": "INT64",
    "metrics.view_through_conversions": "INT64",
    "metrics.view_through_conversions_from_location_asset_click_to_call": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_directions": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_menu": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_order": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_other_engagement": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_store_visits": "DOUBLE",
    "metrics.view_through_conversions_from_location_asset_website": "DOUBLE",
}

METRIC_TO_DLT_TYPE = {
    "INT64": "bigint",
    "DOUBLE": "double",
    "STRING": "text",
    "ENUM": "text",
    # TODO: support message types
    # "MESSAGE": "string",
}


def dlt_metrics_schema(metrics: List[str]):
    """
    Returns a dictionary with only the metrics that are
    present in the given list of metrics.
    """
    schema = {}
    for metric in metrics:
        typ = METRICS_SCHEMA.get(metric)
        if typ is None:
            raise ValueError(f"Unsupported metric {metric}")

        if typ not in METRIC_TO_DLT_TYPE:
            raise ValueError(f"Unsupported metric '{metric}' of type '{typ}'")

        # ???: can we make these non-nullable?
        schema[field.to_column(metric)] = {
            "data_type": METRIC_TO_DLT_TYPE[typ],
        }
    return schema
