use leptos::prelude::*;
use leptos::task::spawn_local;
use crate::components::prelude::*;
use crate::components::card::{Card, CardVariant};
use crate::components::dropdown::Dropdown;
use crate::api::get_user_statistics;
use rust_shared::repository::model::{PoolType, Period, UserStatistics};

#[derive(Clone, Copy, PartialEq)]
pub enum TimePeriod {
    Week,
    Month,
}

#[derive(Clone, Copy, PartialEq)]
pub enum ProxyPool {
    Residential,
    Datacenter,
    ResidentialPremium,
    Mobile,
}

impl ProxyPool {
    fn to_pool_type(&self) -> PoolType {
        match self {
            ProxyPool::Residential => PoolType::Residential,
            ProxyPool::Datacenter => PoolType::Datacenter,
            ProxyPool::ResidentialPremium => PoolType::ResidentialPremium,
            ProxyPool::Mobile => PoolType::Mobile,
        }
    }
}

impl TimePeriod {
    fn to_period(&self) -> Period {
        match self {
            TimePeriod::Week => Period::Week,
            TimePeriod::Month => Period::Month,
        }
    }
}



fn proxy_pool_display(pool: &ProxyPool) -> String {
    match pool {
        ProxyPool::Residential => t8s!("Residential").to_string(),
        ProxyPool::Datacenter => t8s!("Datacenter").to_string(),
        ProxyPool::ResidentialPremium => t8s!("Residential Premium").to_string(),
        ProxyPool::Mobile => t8s!("Mobile").to_string(),
    }
}

#[component]
fn TotalTrafficSummary(
    total_traffic: i64,
    total_extra_traffic: i64,
) -> impl IntoView {
    let format_traffic = |bytes: i64| -> (String, &'static str) {
        let gb = bytes as f64 / (1024.0);
        if gb >= 1.0 {
            (format!("{:.1}", gb), t8s!("GB"))
        } else {
            let mb = bytes as f64;
            (format!("{:.0}", mb), t8s!("MB"))
        }
    };
    
    let (traffic_amount, traffic_unit) = format_traffic(total_traffic);
    let (extra_traffic_amount, extra_traffic_unit) = format_traffic(total_extra_traffic);
    
    view! {
        <div class="flex flex-col items-start gap-2 w-full" id="total-traffic-container">
            <h3 class="font-bold text-xs leading-[18px] tracking-tight uppercase text-[var(--main-light-40)] w-full" id="total-traffic-title">
                {t8s!("Total Traffic")}
            </h3>
            <div class="flex flex-row items-start gap-2 w-full" id="total-traffic-data-container">
                <div class="flex flex-row items-start gap-1 flex-none" id="total-traffic-data">
                    <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light)]" id="total-traffic-amount">
                        {traffic_amount}
                    </span>
                    <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light-40)]" id="total-traffic-unit">
                        {traffic_unit}
                    </span>
                </div>
                
                {if total_extra_traffic > 0 {
                    view! {
                        <>
                            <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light-40)]" id="plus-sign">
                                "+"
                            </span>
                            
                            <div class="flex flex-row items-end gap-1 flex-1" id="extra-traffic-data-container">
                                <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light)]" id="extra-traffic-amount">
                                    {extra_traffic_amount}
                                </span>
                                <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light-40)]" id="extra-traffic-unit">
                                    {extra_traffic_unit}
                                </span>
                                <span class="font-normal text-base leading-[22px] tracking-tight text-[var(--main-light-80)]" id="extra-traffic-label">
                                    {t8s!("(Extra Traffic)")}
                                </span>
                            </div>
                        </>
                    }.into_any()
                } else {
                    view! { <div></div> }.into_any()
                }}
            </div>
        </div>
    }
}

#[component]
fn DailyUsageItem(
    date: String,
    traffic: i64,
    requests: i64,
) -> impl IntoView {
    let format_traffic = |bytes: i64| -> (String, &'static str) {
        let gb = bytes as f64 / 1024.0;
        if gb >= 1.0 {
            (format!("{:.1}", gb), t8s!("GB"))
        } else {
            let mb = bytes as f64;
            (format!("{:.0}", mb), t8s!("MB"))
        }
    };

    let format_requests = |count: i64| -> String {
        if count >= 1000 {
            let s = count.to_string();
            let mut result = String::new();
            let chars: Vec<char> = s.chars().collect();
            for (i, c) in chars.iter().enumerate() {
                if i > 0 && (chars.len() - i) % 3 == 0 {
                    result.push(',');
                }
                result.push(*c);
            }
            result
        } else {
            count.to_string()
        }
    };
    
    let (traffic_amount, traffic_unit) = format_traffic(traffic);
    let requests_formatted = format_requests(requests);

    log::debug!("DailyUsageItem: date: {}, traffic: {}, requests: {}, formatted traffic: {}{}", date, traffic, requests, traffic_amount, traffic_unit);
    
    view! {
        <div class="flex flex-col items-start gap-3 w-full" id="date-container">
            <div class="w-full font-semibold text-base leading-[22px] tracking-tight text-[var(--main-light)]" id="usage-date">
                {date}
            </div>
            
            <div class="flex flex-col items-start gap-1 w-full" id="traffic-requests-container">
                <div class="flex flex-row items-end gap-2 w-full" id="traffic-data-container">
                    <span class="font-bold text-xs leading-[18px] tracking-tight uppercase text-[var(--main-light-40)] flex-none" id="traffic-title">
                        {t8s!("Traffic")}
                    </span>
                    <div class="flex flex-row items-start gap-1 flex-none" id="traffic-data">
                        <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light)]" id="traffic-amount">
                            {traffic_amount}
                        </span>
                        <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light-40)]" id="traffic-unit">
                            {traffic_unit}
                        </span>
                    </div>
                </div>
                
                <div class="flex flex-row items-end gap-2 w-full" id="requests-data-container">
                    <span class="font-bold text-xs leading-[18px] tracking-tight uppercase text-[var(--main-light-40)] flex-none" id="requests-title">
                        {t8s!("Requests")}
                    </span>
                    <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light)] flex-none" id="requests-amount">
                        {requests_formatted}
                    </span>
                </div>
            </div>
        </div>
    }
}

#[component]
fn PeriodToggle(
    selected_period: ReadSignal<TimePeriod>,
    on_change: Callback<TimePeriod>,
) -> impl IntoView {
    view! {
        <div class="flex flex-row justify-between items-center w-full h-[46px] rounded-[14px] selector" id="period-toggle">
            <button 
                class=move || format!(
                    "flex flex-row justify-center items-center gap-[10px] flex-1 h-[46px] font-semibold text-base leading-[22px] tracking-tight border-none cursor-pointer transition-colors {}",
                    if matches!(selected_period.get(), TimePeriod::Week) {
                        "selected"
                    } else {
                        ""
                    }
                )
                on:click=move |_| on_change.run(TimePeriod::Week)
                id="week-button"
            >
                {t8s!("Week")}
            </button>
            
            <button 
                class=move || format!(
                    "flex flex-row justify-center items-center gap-[10px] flex-1 h-[46px] font-semibold text-base leading-[22px] tracking-tight border-none cursor-pointer transition-colors {}",
                    if matches!(selected_period.get(), TimePeriod::Month) {
                        "selected"
                    } else {
                        ""
                    }
                )
                on:click=move |_| on_change.run(TimePeriod::Month)
                id="month-button"
            >
                {t8s!("Month")}
            </button>
        </div>
    }
}

#[component]
pub fn UsageStatistics() -> impl IntoView {
    let (selected_pool, set_selected_pool) = signal(ProxyPool::Residential);
    let (selected_period, set_selected_period) = signal(TimePeriod::Week);
    let (statistics_data, set_statistics_data) = signal(None::<UserStatistics>);
    let (loading, set_loading) = signal(false);
    
    {
        let pool = selected_pool;
        let period = selected_period;
        Effect::new(move |_| {
            let pool_val = pool.get();
            let period_val = period.get();
            
            spawn_local(async move {
                set_loading.set(true);
                match get_user_statistics(pool_val.to_pool_type(), period_val.to_period()).await {
                    Ok(Some(stats)) => {
                        set_statistics_data.set(Some(stats));
                    }
                    Ok(None) => {
                        log::warn!("No statistics data returned from API");
                        set_statistics_data.set(None);
                    }
                    Err(e) => {
                        log::error!("Failed to fetch statistics: {:?}", e);
                        set_statistics_data.set(None);
                    }
                }
                set_loading.set(false);
            });
        });
    }
    
    view! {
        <Card
            variant=CardVariant::L2
            max_width="w-full"
            padding="p-4"
            class="w-full h-full flex flex-col"
            id="usage-statistics-card"
        >
            <div class="flex flex-col items-start gap-3 w-full mb-4" id="usage-statistics-container">
                <h2 class="font-bold text-xs leading-[18px] tracking-tight uppercase text-[var(--main-light-40)] w-full" id="usage-statistics-title">
                    {t8s!("Usage Statistics")}
                </h2>
                <Dropdown 
                    selected=selected_pool
                    options=move || vec![ProxyPool::Residential, ProxyPool::Datacenter, ProxyPool::ResidentialPremium, ProxyPool::Mobile]
                    on_change=Callback::new(move |pool| set_selected_pool.set(pool))
                    display_fn=proxy_pool_display
                    id="pool-dropdown"
                />
            </div>
            
            <div class="w-full flex-1 bg-[var(--other-light-5)] rounded-[14px] relative mb-4" id="statistics-data-container">
                <div class="absolute inset-3 overflow-y-auto" id="statistics-data">
                    {move || {
                        if loading.get() {
                            view! {
                                <div class="flex items-center justify-center h-full">
                                    <div class="text-[var(--main-light-40)] text-center">
                                        {t8s!("Loading statistics...")}
                                    </div>
                                </div>
                            }.into_any()
                        } else if let Some(stats) = statistics_data.get() {
                            if stats.usage.is_empty() {
                                view! {
                                    <div class="flex flex-col items-start gap-4" id="statistics-content">
                                        <TotalTrafficSummary 
                                            total_traffic=stats.total.traffic
                                            total_extra_traffic=stats.total.extra_traffic
                                        />
                                        
                                        <div class="w-full h-px bg-[var(--other-light-20)]" id="separator-1"></div>
                                        
                                        <div class="flex items-center justify-center w-full py-8">
                                            <div class="text-[var(--main-light-40)] text-center">
                                                {t8s!("No usage data for this period")}
                                            </div>
                                        </div>
                                    </div>
                                }.into_any()
                            } else {
                                view! {
                                    <div class="flex flex-col items-start gap-4" id="statistics-content">
                                        <TotalTrafficSummary 
                                            total_traffic=stats.total.traffic
                                            total_extra_traffic=stats.total.extra_traffic
                                        />
                                        
                                        <div class="w-full h-px bg-[var(--other-light-20)]" id="separator-1"></div>
                                        
                                        {stats.usage.clone().into_iter().enumerate().map(|(i, usage_item)| {
                                            view! {
                                                <div class="w-full">
                                                    <DailyUsageItem 
                                                        date=usage_item.used_at
                                                        traffic=usage_item.traffic
                                                        requests=usage_item.request
                                                    />
                                                    {if i < stats.usage.len() - 1 { // Don't show separator after last item
                                                        view! {
                                                            <div class="w-full h-px bg-[var(--other-light-20)] mt-4" id=format!("separator-{}", i + 2)></div>
                                                        }.into_any()
                                                    } else {
                                                        view! { <div class="hidden"></div> }.into_any()
                                                    }}
                                                </div>
                                            }
                                        }).collect_view()}
                                    </div>
                                }.into_any()
                            }
                        } else {
                            view! {
                                <div class="flex items-center justify-center h-full">
                                    <div class="text-[var(--main-light-40)] text-center">
                                        {t8s!("No statistics available")}
                                    </div>
                                </div>
                            }.into_any()
                        }
                    }}
                </div>
                
            </div>
            
            <PeriodToggle 
                selected_period=selected_period
                on_change=Callback::new(move |period| set_selected_period.set(period))
            />
        </Card>
    }
}
