/*
 * -------------------------------------------------------------------------
 * This file is part of the MindStudio project.
 * Copyright (c) 2025 Huawei Technologies Co.,Ltd.
 *
 * MindStudio is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *          http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * -------------------------------------------------------------------------
 */
import React, { useEffect, useRef, useState } from 'react';
import { MIChart } from '@insight/lib/components';
import type { ChartsHandle } from '@insight/lib';
import { useTranslation } from 'react-i18next';
import { type EChartsOption } from 'echarts';
import { Session } from '../entity/session';
import { observer } from 'mobx-react';
import { type DetailData } from '../utils/RequestUtils';
import { getNewDetailData } from './dataHandler';
import { safeStr } from '@insight/lib/utils';

interface treemap {
    name: string;
    value: number;
    children?: treemap[];
};
const transformData = (node: DetailData, t: any, depth: number): treemap => {
    const convertedNode: treemap = {
        name: `${t(node.name)}`,
        value: node.size,
    };
    if (depth > 8) { return convertedNode; }
    if (node.subNodes && node.subNodes.length > 0) {
        convertedNode.children = node.subNodes.map(subNode => transformData(subNode, t, depth + 1));
    }
    return convertedNode;
};

const getColorGradientByGroup = (depth: number): string => {
    const baseHues = [210, 0, 30, 120];
    const group = depth % 4;
    const posInGroup = Math.floor(depth / 4);
    const saturation = 80;
    const lightnessStart = 30;
    const lightnessEnd = 70;
    const lightness = lightnessStart + ((lightnessEnd - lightnessStart) * posInGroup);
    return `hsl(${baseHues[group]}, ${saturation}%, ${lightness}%)`;
};

const mapLevelOption = (): any => {
    const levels = [];
    let i = 7;
    while (--i >= 0) {
        levels.push({
            itemStyle: {
                color: getColorGradientByGroup(i),
                borderColor: getColorGradientByGroup(i),
                borderWidth: 5,
                gapWidth: 5,
            },
            emphasis: {
                itemStyle: {
                    borderColor: '#ddd',
                },
            },
        });
    }
    return levels;
};

const getLevelOption = (): any => {
    return [
        {
            itemStyle: {
                color: '#fff',
                borderColor: '#fff',
                borderWidth: 5,
                gapWidth: 5,
            },
            upperLabel: {
                show: false,
            },
        },
        ...mapLevelOption(),
    ];
};

const getSeries = (chartData: treemap[], t: any): any => {
    return [{
        name: t('MemoryDisassembly'),
        type: 'treemap',
        visibleMin: 300,
        label: {
            show: true,
            formatter: (params: any): string => {
                const { name, value } = params.data;
                const isB: boolean = (value / 1024 / 1024).toFixed(0) === '0';
                return isB ? safeStr(`${name}:${value}B`) : safeStr(`${name}: ${(value / 1024 / 1024).toFixed(0)}MB`);
            },
        },
        upperLabel: {
            show: true,
            height: 30,
        },
        levels: getLevelOption(),
        data: chartData,
    }];
};
const MemorySliceChart: any = observer(({ session }: { session: Session }): React.ReactElement => {
    const { t } = useTranslation('leaks');
    const chartRef = useRef<ChartsHandle>(null);
    const [loading, setLoading] = useState(true);
    const [chartOptions, setChartOptions] = useState<EChartsOption>({});
    const [chartData, setChartData] = useState<treemap[]>([]);
    useEffect(() => {
        setChartOptions({
            xAxis: {
                show: false,
            },
            yAxis: {
                show: false,
            },
            legend: {
                show: false,
            },
            tooltip: {
                formatter: (params: any): string => {
                    const { name, value } = params.data;
                    const isB: boolean = (value / 1024 / 1024).toFixed(0) === '0';
                    return isB ? safeStr(`${name}:${value}B`) : safeStr(`${name}: ${(value / 1024 / 1024).toFixed(0)}MB`);
                },
            },
            series: getSeries(chartData, t) as echarts.SeriesOption,
        });
        setLoading(false);
    }, [chartData]);
    useEffect(() => {
        getNewDetailData(session);
    }, [session.memoryStamp, t]);
    useEffect(() => {
        setChartData([transformData(session.memoryData, t, 0)]);
    }, [session.memoryData, t]);
    return <>
        {chartData.length === 1 && chartData[0].value === 0
            ? <div style={{ position: 'relative', top: 40, paddingBottom: 30 }}>
                {(t('noDisassemblyData', { returnObjects: true }) as string[]).map((item, index) => <div key={index}>{item}</div>)}
            </div>
            : <MIChart
                ref={chartRef}
                height="350px"
                loading={loading}
                options={chartOptions}
            />
        }
    </>;
});
export default MemorySliceChart;