<!-- 天气折线图弹窗 -->
<script setup lang="ts">
    import dayjs from 'dayjs'
    import { Echarts, useEcharts } from '@/components/Echarts'
    import * as WeatherAPI from '@/api/model/weather'

    const props = defineProps<{
        visible: boolean
        type: 'rain' | 'temp' | 'wind' | 'severe'
        lon: string | number
        lat: string | number
    }>()

    const emit = defineEmits(['close'])

    const [register, chart] = useEcharts()

    // 标题映射
    const titleMap = {
        rain: '降雨预报',
        temp: '温度预报',
        wind: '大风预报',
        severe: '强对流预报',
    }

    // Y 轴单位映射
    const unitMap = {
        rain: 'mm',
        temp: '°C',
        wind: 'km/h',
        severe: '',
    }

    // 加载状态
    const loading = ref(false)
    const errorMsg = ref('')
    const updateText = ref('')

    // 请求序号，用于取消旧请求
    let requestSeq = 0

    // 监听 visible/type/lon/lat 变化，拉取数据
    watch(
        () => [props.visible, props.type, props.lon, props.lat] as const,
        async ([visible]) => {
            if (!visible) {
                return
            }
            if (!props.lon || !props.lat) {
                errorMsg.value = '未设置农场坐标位置'
                return
            }
            await fetchWeatherData()
        },
        { immediate: true },
    )

    async function fetchWeatherData() {
        const seq = ++requestSeq
        loading.value = true
        errorMsg.value = ''
        try {
            let data: any
            switch (props.type) {
                case 'rain':
                    data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
                    if (seq !== requestSeq) return
                    await nextTick()
                    renderRainChart(data.data)
                    break
                case 'temp':
                    data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
                    if (seq !== requestSeq) return
                    await nextTick()
                    renderTempChart(data.data)
                    break
                case 'wind':
                    data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
                    if (seq !== requestSeq) return
                    await nextTick()
                    renderWindChart(data.data)
                    break
                case 'severe':
                    data = await WeatherAPI.severeForecast(String(props.lon), String(props.lat))
                    if (seq !== requestSeq) return
                    await nextTick()
                    renderSevereChart(data)
                    break
            }
            updateText.value = `数据更新时间: ${dayjs().format('YYYY-MM-DD HH:mm')}`
        } catch (e: any) {
            console.error('获取天气数据失败:', e)
            // 如果在此期间有新请求，不覆盖其错误状态
            if (seq !== requestSeq) {
                return
            }
            errorMsg.value = '数据加载失败'
        } finally {
            loading.value = false
        }
    }

    // 渲染空图表
    function renderEmptyChart(hint?: string) {
        chart.setOption(
            {
                title: { show: false },
                tooltip: { show: false },
                grid: { top: 60, right: 20, bottom: 40, left: 40 },
                xAxis: { type: 'category', data: [], show: false },
                yAxis: { type: 'value', show: false },
                series: [],
                graphic: {
                    type: 'text',
                    left: 'center',
                    top: 'middle',
                    style: {
                        text: hint || '暂无数据',
                        fontSize: 16,
                        fill: '#bbb',
                    },
                },
            },
            { notMerge: true },
        )
    }

    function renderRainChart(data: any) {
        if (!data?.daily || !Array.isArray(data.daily)) {
            renderEmptyChart('暂无预报数据')
            return
        }
        const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
        const precip = data.daily.map((d: any) => Number.parseFloat(d.precip) || 0)

        chart.setOption(
            {
                title: { show: false },
                tooltip: { trigger: 'axis' },
                legend: {
                    top: 0,
                    textStyle: { fontSize: 14, color: '#333' },
                },
                grid: { top: 60, right: 20, bottom: 40, left: 40 },
                xAxis: {
                    type: 'category',
                    data: dates,
                    axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
                    axisLine: { lineStyle: { color: '#eee' } },
                    axisTick: { show: false },
                },
                yAxis: {
                    type: 'value',
                    name: '(mm)',
                    nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
                    axisLabel: { fontSize: 14, color: '#bbb' },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
                },
                series: [
                    {
                        name: '降水量',
                        type: 'line',
                        data: precip,
                        smooth: true,
                        showSymbol: true,
                        symbolSize: 6,
                        itemStyle: { color: '#6db876' },
                        label: {
                            show: true,
                            position: 'top',
                            fontSize: 12,
                            color: '#666',
                        },
                        lineStyle: { color: '#6db876', width: 2 },
                        areaStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: 'rgba(109,184,118,0.3)' },
                                    { offset: 1, color: 'rgba(109,184,118,0)' },
                                ],
                            },
                        },
                    },
                ],
            },
            { notMerge: true },
        )
    }

    function renderTempChart(data: any) {
        if (!data?.daily || !Array.isArray(data.daily)) {
            renderEmptyChart('暂无预报数据')
            return
        }
        const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
        const tempMax = data.daily.map((d: any) => Number.parseFloat(d.tempMax) || 0)
        const tempMin = data.daily.map((d: any) => Number.parseFloat(d.tempMin) || 0)

        chart.setOption(
            {
                title: { show: false },
                tooltip: { trigger: 'axis' },
                legend: {
                    top: 0,
                    textStyle: { fontSize: 14, color: '#333' },
                },
                grid: { top: 60, right: 20, bottom: 40, left: 40 },
                xAxis: {
                    type: 'category',
                    data: dates,
                    axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
                    axisLine: { lineStyle: { color: '#eee' } },
                    axisTick: { show: false },
                },
                yAxis: {
                    type: 'value',
                    name: '(°C)',
                    nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
                    axisLabel: { fontSize: 14, color: '#bbb' },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
                },
                series: [
                    {
                        name: '最高温度',
                        type: 'line',
                        data: tempMax,
                        smooth: true,
                        showSymbol: true,
                        symbolSize: 6,
                        itemStyle: { color: '#e74c3c' },
                        label: {
                            show: true,
                            position: 'top',
                            fontSize: 12,
                            color: '#666',
                        },
                        lineStyle: { color: '#e74c3c', width: 2 },
                        areaStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: 'rgba(231,76,60,0.3)' },
                                    { offset: 1, color: 'rgba(231,76,60,0)' },
                                ],
                            },
                        },
                    },
                    {
                        name: '最低温度',
                        type: 'line',
                        data: tempMin,
                        smooth: true,
                        showSymbol: true,
                        symbolSize: 6,
                        itemStyle: { color: '#3498db' },
                        label: {
                            show: true,
                            position: 'bottom',
                            fontSize: 12,
                            color: '#666',
                        },
                        lineStyle: { color: '#3498db', width: 2 },
                        areaStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: 'rgba(52,152,219,0.2)' },
                                    { offset: 1, color: 'rgba(52,152,219,0)' },
                                ],
                            },
                        },
                    },
                ],
            },
            { notMerge: true },
        )
    }

    function renderWindChart(data: any) {
        if (!data?.daily || !Array.isArray(data.daily)) {
            renderEmptyChart('暂无预报数据')
            return
        }
        const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
        const windDay = data.daily.map((d: any) => Number.parseFloat(d.windSpeedDay) || 0)
        const windNight = data.daily.map((d: any) => Number.parseFloat(d.windSpeedNight) || 0)

        chart.setOption(
            {
                title: { show: false },
                tooltip: { trigger: 'axis' },
                legend: {
                    top: 0,
                    textStyle: { fontSize: 14, color: '#333' },
                },
                grid: { top: 60, right: 20, bottom: 40, left: 40 },
                xAxis: {
                    type: 'category',
                    data: dates,
                    axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
                    axisLine: { lineStyle: { color: '#eee' } },
                    axisTick: { show: false },
                },
                yAxis: {
                    type: 'value',
                    name: '(km/h)',
                    nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
                    axisLabel: { fontSize: 14, color: '#bbb' },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
                },
                series: [
                    {
                        name: '白天风速',
                        type: 'line',
                        data: windDay,
                        smooth: true,
                        showSymbol: true,
                        symbolSize: 6,
                        itemStyle: { color: '#e67e22' },
                        label: {
                            show: true,
                            position: 'top',
                            fontSize: 12,
                            color: '#666',
                        },
                        lineStyle: { color: '#e67e22', width: 2 },
                        areaStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: 'rgba(230,126,34,0.3)' },
                                    { offset: 1, color: 'rgba(230,126,34,0)' },
                                ],
                            },
                        },
                    },
                    {
                        name: '夜间风速',
                        type: 'line',
                        data: windNight,
                        smooth: true,
                        showSymbol: true,
                        symbolSize: 6,
                        itemStyle: { color: '#3498db' },
                        label: {
                            show: true,
                            position: 'bottom',
                            fontSize: 12,
                            color: '#666',
                        },
                        lineStyle: { color: '#3498db', width: 2 },
                        areaStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: 'rgba(52,152,219,0.2)' },
                                    { offset: 1, color: 'rgba(52,152,219,0)' },
                                ],
                            },
                        },
                    },
                ],
            },
            { notMerge: true },
        )
    }

    function renderSevereChart(data: any) {
        if (!data?.elements || !Array.isArray(data.elements) || data.elements.length === 0) {
            renderEmptyChart('暂无预报数据')
            return
        }
        const elements = data.elements

        // 从第一个要素提取时间轴
        const firstElement = elements[0]
        if (
            !firstElement?.timeDataList ||
            !Array.isArray(firstElement.timeDataList) ||
            firstElement.timeDataList.length === 0
        ) {
            renderEmptyChart('暂无预报数据')
            return
        }
        const times = firstElement.timeDataList.map((d: any) => dayjs(d.forecastTime).format('HH:mm'))

        const colors = ['#e74c3c', '#3498db', '#f39c12']

        const series = elements.map((el: any, idx: number) => ({
            name: el.name,
            type: 'line',
            data: el.timeDataList.map((d: any) => d.value || 0),
            smooth: true,
            showSymbol: true,
            symbolSize: 6,
            itemStyle: { color: colors[idx % colors.length] },
            label: {
                show: true,
                position: 'top',
                fontSize: 12,
                color: '#666',
            },
            lineStyle: { color: colors[idx % colors.length], width: 2 },
            areaStyle: {
                color: {
                    type: 'linear',
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                        { offset: 0, color: `${colors[idx % colors.length]}4D` },
                        { offset: 1, color: `${colors[idx % colors.length]}00` },
                    ],
                },
            },
        }))

        // Y 轴单位：取第一个要素的单位
        const unit = elements[0]?.timeDataList?.[0]?.unit || ''

        chart.setOption(
            {
                title: { show: false },
                tooltip: { trigger: 'axis' },
                legend: {
                    top: 0,
                    textStyle: { fontSize: 14, color: '#333' },
                },
                grid: { top: 60, right: 20, bottom: 40, left: 40 },
                xAxis: {
                    type: 'category',
                    data: times,
                    axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
                    axisLine: { lineStyle: { color: '#eee' } },
                    axisTick: { show: false },
                },
                yAxis: {
                    type: 'value',
                    name: `(${unit})`,
                    nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
                    axisLabel: { fontSize: 14, color: '#bbb' },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
                },
                series,
            },
            { notMerge: true },
        )
    }
</script>

<template>
    <view v-show="visible" class="weather-chart-overlay" @tap="emit('close')">
        <view class="chart-popup" @tap.stop>
            <!-- 标题栏 -->
            <view class="popup-header">
                <text class="popup-title">{{ titleMap[type] }}</text>
                <view class="close-btn" @tap="emit('close')">
                    <text class="close-icon">×</text>
                </view>
            </view>

            <!-- 加载/错误状态 -->
            <view v-if="loading" class="chart-status">
                <text>加载中...</text>
            </view>
            <view v-else-if="errorMsg" class="chart-status error">
                <text>{{ errorMsg }}</text>
                <view class="retry-btn" @tap="fetchWeatherData">
                    <text>重试</text>
                </view>
            </view>

            <!-- 图表区域 -->
            <view v-show="!loading && !errorMsg" class="chart-container">
                <Echarts @register="register" class="chart-area" />
            </view>

            <!-- 更新时间 -->
            <view v-if="updateText && !loading && !errorMsg" class="update-info">
                <text class="update-text">{{ updateText }}</text>
            </view>
        </view>
    </view>
</template>

<style lang="scss" scoped>
    .weather-chart-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 998;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: rgba(0, 0, 0, 0.3);
    }

    .chart-popup {
        width: 90%;
        max-width: 600px;
        background: linear-gradient(180deg, rgba(200, 255, 200, 1) 0%, rgba(255, 255, 255, 1) 40%);
        border-radius: 32rpx;
        position: relative;
        overflow: hidden;
        transform: translateY(-40%);
    }

    .popup-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 10rpx 30rpx 10rpx;

        .popup-title {
            font-size: 36rpx;
            font-weight: 600;
            color: #333;
        }

        .close-btn {
            width: 60rpx;
            height: 60rpx;
            display: flex;
            align-items: center;
            justify-content: center;

            &:active {
                opacity: 0.6;
            }

            .close-icon {
                font-size: 36rpx;
                color: #ccc;
                font-weight: 300;
            }
        }
    }

    .chart-status {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 400rpx;
        font-size: 28rpx;
        color: #999;

        &.error {
            color: #e74c3c;
        }
    }

    .retry-btn {
        margin-top: 20rpx;
        padding: 16rpx 40rpx;
        background-color: #5db66f;
        color: #fff;
        border-radius: 32rpx;
        font-size: 26rpx;

        &:active {
            opacity: 0.8;
        }
    }

    .chart-container {
        width: 100%;
        height: 350rpx;
    }

    .chart-area {
        width: 100%;
        height: 100%;
    }

    .update-info {
        padding: 0 30rpx 20rpx;
        text-align: center;

        .update-text {
            font-size: 20rpx;
            color: #bbb;
        }
    }
</style>
