import { useEffect, useState } from 'react'
import { useAppSelector } from '@/redux/store';
import { useTranslations } from 'next-intl';
import dynamic from 'next/dynamic';
import Cookies from 'universal-cookie';
const ReactApexChart = dynamic(() => import('react-apexcharts'), {
    ssr: false,
});
import { useDispatch } from 'react-redux';
import { AppDispatch } from '@/redux/store';
import { setCurrentMembersGeneralOverviewDuration } from '@/redux/features/statistics-slice'

export default function MembersOverviewChart()
{
    // get needed redux state
    const report = useAppSelector((state) => state.statisticsReducer.value.report)
    const currentMembersGeneralOverviewDuration = useAppSelector((state) => state.statisticsReducer.value.currentMembersGeneralOverviewDuration)
    const themeType = useAppSelector((state) => state.themeTypeReducer.value.themeType)
    // declare global variables
    const dispatch = useDispatch<AppDispatch>()
    const cookies = new Cookies();
    const t = useTranslations('statistics');
    const locale = cookies.get("NEXT_LOCALE")
    const isRtl = locale == 'ar' ? true : false
    const isDark = themeType == 'dark' ? true : false
    const [chartSeries , setChartSeries] = useState<{}[]>([]);
    const [labels , setLabels] = useState<string[]>([])
    // revenue Chart
    // prepare chart series and handle the transaction between currentMembersGeneralOverviewDuration
    useEffect(() => {
        // if chart duration is set to this week
        if(currentMembersGeneralOverviewDuration == 'thisWeek')
        {
            // set the labels       
            setLabels([t('sat') , t('sun') , t('mon') , t('tue') , t('wed') , t('thu') , t('fri')])
            // init this weekdata
            let data_thisWeek = {
                'sat': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'sun': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'mon': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'tue': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'wed': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'thu': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                },
                'fri': {
                    'totalMembers': 0,
                    'totalActiveSubs': 0,
                    'totalUnActiveSubs': 0,
                    'totalMansMembers': 0,
                    'totalGirlsMembers': 0,
                }
            }
            // if there is a data from the backend we overwrite the currentData
            if(report?.membersGeneralOverview?.value.thisWeek.days) {        
                data_thisWeek = report?.membersGeneralOverview?.value.thisWeek.days;
            }
            // prepare the chart series
            setChartSeries([
                {
                    name: t('totalMembers'),
                    data: [data_thisWeek['sat']['totalMembers'], data_thisWeek['sun']['totalMembers'], data_thisWeek['mon']['totalMembers'], data_thisWeek['tue']['totalMembers'], data_thisWeek['wed']['totalMembers'], data_thisWeek['thu']['totalMembers'], data_thisWeek['fri']['totalMembers']],
                },
                {
                    name: t('totalActiveSubs'),
                    data: [data_thisWeek['sat']['totalActiveSubs'], data_thisWeek['sun']['totalActiveSubs'], data_thisWeek['mon']['totalActiveSubs'], data_thisWeek['tue']['totalActiveSubs'], data_thisWeek['wed']['totalActiveSubs'], data_thisWeek['thu']['totalActiveSubs'], data_thisWeek['fri']['totalActiveSubs']],
                },
                {
                    name: t('totalUnActiveSubs'),
                    data: [data_thisWeek['sat']['totalUnActiveSubs'], data_thisWeek['sun']['totalUnActiveSubs'], data_thisWeek['mon']['totalUnActiveSubs'], data_thisWeek['tue']['totalUnActiveSubs'], data_thisWeek['wed']['totalUnActiveSubs'], data_thisWeek['thu']['totalUnActiveSubs'], data_thisWeek['fri']['totalUnActiveSubs']],
                },
                {
                    name: t('totalMansMembers'),
                    data: [data_thisWeek['sat']['totalMansMembers'], data_thisWeek['sun']['totalMansMembers'], data_thisWeek['mon']['totalMansMembers'], data_thisWeek['tue']['totalMansMembers'], data_thisWeek['wed']['totalMansMembers'], data_thisWeek['thu']['totalMansMembers'], data_thisWeek['fri']['totalMansMembers']],
                },
                {
                    name: t('totalGirlsMembers'),
                    data: [data_thisWeek['sat']['totalGirlsMembers'], data_thisWeek['sun']['totalGirlsMembers'], data_thisWeek['mon']['totalGirlsMembers'], data_thisWeek['tue']['totalGirlsMembers'], data_thisWeek['wed']['totalGirlsMembers'], data_thisWeek['thu']['totalGirlsMembers'], data_thisWeek['fri']['totalGirlsMembers']],
                },
            ])
        }
        // if chart duration is set to this month
        else if(currentMembersGeneralOverviewDuration == 'thisMonth')
        {
            let thisMonthTotalSum : {
                week : number,
                thisWeekSum : {
                    "totalMembers": number,
                    "totalActiveSubs": number,
                    "totalUnActiveSubs": number,
                    "totalMansMembers": number,
                    "totalGirlsMembers": number
                }
            }[];
            if(report?.membersGeneralOverview?.value.thisMonth)
            {
                // if we founded a data for the current month
                thisMonthTotalSum = report?.membersGeneralOverview?.value.thisMonth.weeks.map((v : any , i : number) : {
                    week : number,
                    thisWeekSum : {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                } => {
                    // we init the this week sum
                    let thisWeekSum = {
                            "totalMembers": 0,
                            "totalActiveSubs": 0,
                            "totalUnActiveSubs": 0,
                            "totalMansMembers": 0,
                            "totalGirlsMembers": 0
                        }
                    // we map through this month weeks
                    v.days.map((w : {
                        'sat': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'sun': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'mon': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'tue': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'wed': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'thu': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        },
                        'fri': {
                            'totalMembers': number,
                            'totalActiveSubs': number,
                            'totalUnActiveSubs': number,
                            'totalMansMembers': number,
                            'totalGirlsMembers': number,
                        }
                    } , i : number) => {
                        // we loop through week days and we sum there data
                        Object.keys(w).forEach(function(key : "sat" | "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "_id" , index : number) {
                            if(key == '_id') return
                            thisWeekSum.totalMembers = thisWeekSum.totalMembers + w[key].totalMembers
                            thisWeekSum.totalActiveSubs = thisWeekSum.totalActiveSubs + w[key].totalActiveSubs
                            thisWeekSum.totalUnActiveSubs = thisWeekSum.totalUnActiveSubs + w[key].totalUnActiveSubs
                            thisWeekSum.totalMansMembers = thisWeekSum.totalMansMembers + w[key].totalMansMembers
                            thisWeekSum.totalGirlsMembers = thisWeekSum.totalGirlsMembers + w[key].totalGirlsMembers
                        })
                    })
                    // each week we return there sum data
                    return {
                        week: v.week,
                        thisWeekSum: thisWeekSum
                    }
                })
                let labels : [] = [];
                thisMonthTotalSum.forEach(function(v , i) {
                    labels.push(t('week')+ ' ' +thisMonthTotalSum[i]["week"])
                })
                // set the labels       
                setLabels(labels)
                // we setup chart_series ( chart data )
                let a : {
                    name: string,
                    data: {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                }[] = ['totalMembers' , 'totalActiveSubs' , 'totalUnActiveSubs' , 'totalMansMembers' , 'totalGirlsMembers'].map((v : string , i : number) : {
                    name: string,
                    data: {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                } => {
                    let data = thisMonthTotalSum.map((v2 : {
                        week: number,
                        thisWeekSum: {
                            "totalMembers": number,
                            "totalActiveSubs": number,
                            "totalUnActiveSubs": number,
                            "totalMansMembers": number,
                            "totalGirlsMembers": number
                        }
                    },i2 : number) => {
                        let index : 'totalMembers' | 'totalActiveSubs' | 'totalUnActiveSubs' | 'totalMansMembers' | 'totalGirlsMembers' = v;
                        return v2.thisWeekSum[index];
                    })
                    // return the line data
                    return {
                        name: t(v),
                        data: data
                    };
                })
                setChartSeries(a)
            }
            // if there was no data we use default return
            else {
                setChartSeries([
                    {
                        name: '1'+t('week'),
                        data: [0,0,0,0,0],
                    },
                    {
                        name: '2'+t('week'),
                        data:  [0,0,0,0,0],
                    },
                    {
                        name: '3'+t('week'),
                        data:  [0,0,0,0,0],
                    },
                    {
                        name: '4'+t('week'),
                        data:  [0,0,0,0,0],
                    }
                ])
            }
        }
        // if chart duration is set to this month
        else if(currentMembersGeneralOverviewDuration == 'thisYear')
        {
            // set the labels       
            setLabels([t('1month'), t('2month'), t('3month'), t('4month'), t('5month'), t('6month'), t('7month'), t('8month'), t('9month'), t('10month'), t('11month')])
            // check if there is current month report
            let thisYearTotalSum : {
                month: number,
                thisMonthWeeksSum: {
                    "totalMembers": number,
                    "totalActiveSubs": number,
                    "totalUnActiveSubs": number,
                    "totalMansMembers": number,
                    "totalGirlsMembers": number
                }
            }[]
            if(report?.membersGeneralOverview?.value.thisYear)
            {
                // if we founded a data for the current month
                thisYearTotalSum = report?.membersGeneralOverview?.value.thisYear.months.map((v : any , i : number) : {
                    month : number,
                    thisMonthWeeksSum : {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                } => {
                    let summedWeeks = v.weeks.map((w : any , i : number) => {
                        // we map through this month weeks
                        let weekSum = w.days.map((d : {
                            'sat': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'sun': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'mon': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'tue': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'wed': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'thu': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            },
                            'fri': {
                                'totalMembers': number,
                                'totalActiveSubs': number,
                                'totalUnActiveSubs': number,
                                'totalMansMembers': number,
                                'totalGirlsMembers': number,
                            }
                        } , i : number) => {
                            // we init the this week sum
                            let thisWeekSum = {
                                "totalMembers": 0,
                                "totalActiveSubs": 0,
                                "totalUnActiveSubs": 0,
                                "totalMansMembers": 0,
                                "totalGirlsMembers": 0
                            }
                            // we loop through week days and we sum there data
                            Object.keys(d).forEach(function(key : "sat" | "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "_id" , index : number) {
                                if(key == '_id') return
                                thisWeekSum.totalMembers = thisWeekSum.totalMembers + d[key].totalMembers
                                thisWeekSum.totalActiveSubs = thisWeekSum.totalActiveSubs + d[key].totalActiveSubs
                                thisWeekSum.totalUnActiveSubs = thisWeekSum.totalUnActiveSubs + d[key].totalUnActiveSubs
                                thisWeekSum.totalMansMembers = thisWeekSum.totalMansMembers + d[key].totalMansMembers
                                thisWeekSum.totalGirlsMembers = thisWeekSum.totalGirlsMembers + d[key].totalGirlsMembers
                            })
                            // each week we return there sum data
                            return thisWeekSum
                        })
                        return {
                            week: w.week,
                            weekSum: weekSum
                        }
                    })

                    let thisMonthWeeksSum = {
                        "totalMembers": 0,
                        "totalActiveSubs": 0,
                        "totalUnActiveSubs": 0,
                        "totalMansMembers": 0,
                        "totalGirlsMembers": 0
                    }

                    summedWeeks.map((v : {week: number, weekSum: {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }[]},i : number) => {
                        thisMonthWeeksSum.totalMembers += v.weekSum[0].totalMembers
                        thisMonthWeeksSum.totalActiveSubs += v.weekSum[0].totalActiveSubs
                        thisMonthWeeksSum.totalUnActiveSubs += v.weekSum[0].totalUnActiveSubs
                        thisMonthWeeksSum.totalMansMembers += v.weekSum[0].totalMansMembers
                        thisMonthWeeksSum.totalGirlsMembers += v.weekSum[0].totalGirlsMembers
                    })
    
                    return {
                        month: v.month,
                        thisMonthWeeksSum: thisMonthWeeksSum
                    }
                })
                // prepare the labels
                let labels : [] = [];
                thisYearTotalSum.forEach(function(v , i) {
                    labels.push(t(thisYearTotalSum[i]["month"]+"month"))
                })
                setLabels(labels)
                // we setup chart_series ( chart data )
                let a : {
                    name: string,
                    data: {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                }[] = ['totalMembers' , 'totalActiveSubs' , 'totalUnActiveSubs' , 'totalMansMembers' , 'totalGirlsMembers'].map((v : string , i : number) : {
                    name: string,
                    data: {
                        "totalMembers": number,
                        "totalActiveSubs": number,
                        "totalUnActiveSubs": number,
                        "totalMansMembers": number,
                        "totalGirlsMembers": number
                    }
                } => {
                    let data = thisYearTotalSum.map((v2 : {
                        month: number,
                        thisMonthWeeksSum: {
                            "totalMembers": number,
                            "totalActiveSubs": number,
                            "totalUnActiveSubs": number,
                            "totalMansMembers": number,
                            "totalGirlsMembers": number
                        }
                    },i2 : number) => {
                        let index : 'totalMembers' | 'totalActiveSubs' | 'totalUnActiveSubs' | 'totalMansMembers' | 'totalGirlsMembers' = v;
                        return v2.thisMonthWeeksSum[index];
                    })
                    // return the line data
                    return {
                        name: t(v),
                        data: data
                    };
                })
                setChartSeries(a)
            }
            // if there was no data we use default return
            else {
                setChartSeries([
                    {
                        name: '1'+t('week'),
                        data: [0,0,0,0,0],
                    },
                    {
                        name: '2'+t('week'),
                        data:  [0,0,0,0,0],
                    },
                    {
                        name: '3'+t('week'),
                        data:  [0,0,0,0,0],
                    },
                    {
                        name: '4'+t('week'),
                        data:  [0,0,0,0,0],
                    }
                ])
            }
        }
    }, [currentMembersGeneralOverviewDuration])
    // prepare the chart options
    const options : any = {
        series: chartSeries,
        options: {
            chart: {
                height: 325,
                type: 'area',
                fontFamily: 'Nunito, sans-serif',
                zoom: {
                    enabled: false,
                },
                toolbar: {
                    show: false,
                },
            },
            data_thisWeekLabels: {
                enabled: false,
            },
            stroke: {
                show: true,
                curve: 'smooth',
                width: 2,
                lineCap: 'square',
            },
            dropShadow: {
                enabled: true,
                opacity: 0.2,
                blur: 10,
                left: -7,
                top: 22,
            },
            colors: ['#38C172', '#38C172' , '#E3342F' , '#0263FF', '#FF30F7'],
            markers: {
                //discrete: [
                //    {
                //        seriesIndex: 0,
                //        data_thisWeekPointIndex: 1,
                //        fillColor: '#38C172',
                //        strokeColor: 'transparent',
                //        size: 7,
                //    },
                //    {
                //        seriesIndex: 1,
                //        data_thisWeekPointIndex: 1,
                //        fillColor: '#E3342F',
                //        strokeColor: 'transparent',
                //        size: 7,
                //    },
                //],
            },
            labels: labels,
            xaxis: {
                axisBorder: {
                    show: false,
                },
                axisTicks: {
                    show: false,
                },
                crosshairs: {
                    show: true,
                },
                labels: {
                    offsetX: isRtl ? 2 : 0,
                    offsetY: 5,
                    style: {
                        colors: isDark ? '#fff' : '#000',
                        fontSize: '12px',
                        cssClass: 'apexcharts-xaxis-title',
                    },
                },
            },
            yaxis: {
                tickAmount: 7,
                labels: {
                    formatter: (value: number) => {
                        if(value > 1000)
                        {
                            return parseInt(value.toFixed(0)) + t('k')
                        }
                        else {
                            return  parseInt(value.toFixed(0))
                        }
                    },
                    offsetX: isRtl ? -30 : -10,
                    offsetY: 0,
                    style: {
                        colors: isDark ? '#fff' : '#000',
                        fontSize: '12px',
                        cssClass: 'apexcharts-yaxis-title',
                    },
                },
            },
            grid: {
                borderColor: isDark ? '#191E3A' : '#E0E6ED',
                strokeDashArray: 5,
                xaxis: {
                    lines: {
                        show: false,
                    },
                },
                yaxis: {
                    lines: {
                        show: true,
                    },
                },
                padding: {
                    top: 0,
                    right: 0,
                    bottom: 0,
                    left: 0,
                },
            },
            legend: {
                position: 'top',
                horizontalAlign: 'right',
                fontSize: '16px',
                markers: {
                    width: 10,
                    height: 10,
                    offsetX: isRtl ? 5 : -5,
                },
                itemMargin: {
                    horizontal: 10,
                    vertical: 5,
                },
            },
            tooltip: {
                theme: isDark ? 'dark' : 'light',
                x: {
                    show: true,
                },
            },
            fill: {
                type: 'gradient',
                gradient: {
                    shadeIntensity: 1,
                    inverseColors: !1,
                    opacityFrom: isDark ? 0.19 : 0.28,
                    opacityTo: 0.05,
                    stops: isDark ? [100, 100] : [45, 100],
                },
            },
            responsive: [{
                breakpoint: 420,
                options: {
                    yaxis: {
                        show: false,
                        showAlways: false,
                    },
                    legend: {
                        offsetY: 10,
                        height: 60,
                        position: 'bottom',
                        horizontalAlign: 'center',
                        fontSize: '12px',
                        markers: {
                            width: 10,
                            height: 10,
                            offsetX: isRtl ? 5 : -5,
                        },
                        itemMargin: {
                            horizontal: 10,
                            vertical: 5,
                        },
                    },
                }
            }],
        },
    };
    // return the ui
    return (
        <>
            <div className="flex flex-col gap-5 [&_*]:dark:!text-text-dark p-5 lg:w-2/3 w-full shadow border border-secondary-light bg-primary dark:bg-primary-dark rounded-[5px]">
                <h3 className="text-xl font-bold">{t('membersGeneralOverview')}</h3>
                <div className="w-full flex gap-3 justify-end">
                    <button disabled={currentMembersGeneralOverviewDuration == 'thisWeek'} onClick={() => {
                        dispatch(setCurrentMembersGeneralOverviewDuration('thisWeek'))
                    }} className="disabled:dark:opacity-[0.5] disabled:opacity-[0.5]">
                        {t('thisWeek')}
                    </button>
                    <button disabled={currentMembersGeneralOverviewDuration == 'thisMonth'} onClick={() => {
                        dispatch(setCurrentMembersGeneralOverviewDuration('thisMonth'))
                    }} className="disabled:dark:opacity-[0.5] disabled:opacity-[0.5]">
                        {t('thisMonth')}
                    </button>
                    <button disabled={currentMembersGeneralOverviewDuration == 'thisYear'} onClick={() => {
                        dispatch(setCurrentMembersGeneralOverviewDuration('thisYear'))
                    }} className="disabled:dark:opacity-[0.5] disabled:opacity-[0.5]">
                        {t('thisYear')}
                    </button>
                </div>
                <ReactApexChart series={options.series} options={options.options} type="area" height={350} width={'100%'} />
            </div>
        </>
    )
}