<template>
  <div class="device-live page-container">
    <div class="header">
      <a-page-header :title="device?.Name || '设备实时数据'" @back="router.back()">
        <template #subtitle>
          <a-space>
            <a-tag v-if="device?.Status" :color="device.Status === 'ONLINE' ? 'green' : 'red'">
              {{ device.Status === 'ONLINE' ? '在线' : '离线' }}
            </a-tag>
            <span>{{ device?.DeviceType }}</span>
          </a-space>
        </template>
        <template #extra>
          <a-button @click="fetchData">刷新</a-button>
        </template>
      </a-page-header>
    </div>

    <a-card :loading="loading" title="设备属性状态">
      <a-table :data="entities" :pagination="false">
        <template #columns>
          <a-table-column title="属性名称">
             <template #cell="{ record }">
                <span v-if="record.display_name" style="font-weight: bold">{{ record.display_name }}</span>
                <span v-else>{{ record.attributes?.friendly_name || record.entity_id }}</span>
                <div v-if="!record.display_name" style="font-size: 12px; color: var(--color-text-3)">{{ record.entity_id }}</div>
             </template>
          </a-table-column>
          <a-table-column title="实时值" data-index="state">
             <template #cell="{ record }">
                <a-tag v-if="record.cleaned_value !== undefined" color="green" size="large">
                   {{ record.cleaned_value }} (TSDB)
                </a-tag>
                <a-tag v-else color="arcoblue" size="large">{{ record.state }}</a-tag>
             </template>
          </a-table-column>
          <a-table-column title="更新时间" data-index="last_updated">
             <template #cell="{ record }">
                <div v-if="record.cleaned_ts">
                   {{ formatTime(record.cleaned_ts) }}
                </div>
                <div v-else>
                   {{ formatTime(record.last_updated) }}
                </div>
             </template>
          </a-table-column>
          <a-table-column title="操作" :width="120">
             <template #cell="{ record }">
                <a-button 
                    v-if="canToggle(record)"
                    type="primary" 
                    size="small"
                    :status="record.state === 'on' ? 'warning' : 'success'"
                    :loading="actionLoading"
                    @click="handleToggle(record)"
                >
                    <template #icon><icon-thunderbolt /></template>
                    {{ record.state === 'on' ? '关闭' : '开启' }}
                </a-button>
             </template>
          </a-table-column>
        </template>
      </a-table>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getDevice, getSourceDeviceEntities, callSourceService, getDeviceRealtime, type Device, type HAEntity } from '../../api/resource';
import { Message } from '@arco-design/web-vue';
import { IconThunderbolt } from '@arco-design/web-vue/es/icon';

const route = useRoute();
const router = useRouter();
const id = route.params.id as string;

const device = ref<Device>();
const entities = ref<(HAEntity & { cleaned_value?: number; cleaned_ts?: string; display_name?: string })[]>([]);
const loading = ref(false);
const actionLoading = ref(false);
let timer: any = null;

const formatTime = (iso: string) => {
    if(!iso) return '-';
    return new Date(iso).toLocaleString();
}

const fetchData = async () => {
    if (!device.value) {
        // Init Load
        try {
            const res = await getDevice(id);
            device.value = (res as any).data || res;
        } catch (err) {
            Message.error('获取设备信息失败');
            return;
        }
    }

    if (device.value) {
        try {
            // 1. Fetch TSDB Realtime Data (Always attempt)
            let tsdbData: any[] = [];
            try {
               const resTS = await getDeviceRealtime(id);
               tsdbData = (resTS as any).data || resTS || [];
            } catch (e) {
               console.warn("Failed to fetch TSDB data", e);
            }

            // 2. Fetch HA Entities (Optional)
            let baseEntities: HAEntity[] = [];
            if (device.value.SourceID && device.value.ExternalID) {
                try {
                    const res = await getSourceDeviceEntities(device.value.SourceID, device.value.ExternalID);
                    baseEntities = (res as any).data || res;
                } catch (e) {
                    console.warn("Failed to fetch Source entities", e);
                }
            }

            // 3. Merge and Filter based on Attribute Mapping if exists
            let finalEntities: (HAEntity & { cleaned_value?: number; cleaned_ts?: string; display_name?: string })[] = [];
            
            // Map standard keys to user friendly names
            const attributeLabels: Record<string, string> = {
                'power': '有功功率 (W)',
                'voltage': '电压 (V)',
                'current': '电流 (A)',
                'energy': '累计用电 (kWh)',
                'temperature': '温度 (°C)',
                'switch': '开关状态'
            };

            if (device.value.AttributeMapping && Object.keys(device.value.AttributeMapping).length > 0) {
                // If mapping exists, iterate through MAPPING keys (standard attributes)
                Object.entries(device.value.AttributeMapping).forEach(([attrKey, entityID]) => {
                    if (attrKey.endsWith('_formula')) return; // skip formula entries

                    const ent = baseEntities.find((e: HAEntity) => e.entity_id === entityID);
                    
                    // Metric naming in TSDB: sanitized attrKey (not entityID)
                    // Logic in collector: safeMetric = strings.ReplaceAll(metric, ".", "_")
                    // So we look for attrKey in tsdbData
                    const metricName = attrKey.replace(/\./g, '_').replace(/-/g, '_');
                    const matched = tsdbData.find((t: any) => t.metric === metricName);

                    if (ent) {
                        finalEntities.push({
                            ...ent,
                            display_name: attributeLabels[attrKey] || attrKey,
                            cleaned_value: matched?.value,
                            cleaned_ts: matched?.ts
                        });
                    } else if (matched || entityID || device.value?.AttributeMapping?.[attrKey + '_formula']) {
                        // Show if we have:
                        // 1. TSDB data (matched)
                        // 2. Mapped EntityID (even if offline)
                        // 3. Formula (even if no EntityID, e.g. purely calculated)
                        finalEntities.push({
                            entity_id: entityID || attrKey,
                            state: 'N/A', // HA state unknown
                            attributes: {},
                            last_changed: '',
                            last_updated: '',
                            display_name: attributeLabels[attrKey] || attrKey,
                            cleaned_value: matched?.value,
                            cleaned_ts: matched?.ts
                        });
                    }
                });

            } else {
                // Fallback: No mapping
                if (baseEntities.length > 0) {
                     // Use HA entities as base
                     finalEntities = baseEntities.map((ent: HAEntity) => {
                        const metricName = ent.entity_id.replace(/\./g, '_');
                        const matched = tsdbData.find((t: any) => t.metric === metricName);

                        let displayName = ent.attributes?.friendly_name;
                        const domain = ent.entity_id.split('.')[0];
                        // Auto-translate common switch names if default
                        if (!displayName || displayName.toLowerCase() === 'switch') {
                             if (domain === 'switch') displayName = '开关状态';
                             else if (domain === 'light') displayName = '灯光';
                        }

                        if (matched) {
                            return { ...ent, display_name: displayName, cleaned_value: matched.value, cleaned_ts: matched.ts };
                        }
                        return { ...ent, display_name: displayName };
                    });
                } else if (tsdbData.length > 0) {
                    // No HA entities, but we have TSDB data. Show TSDB raw.
                    finalEntities = tsdbData.map((t: any) => ({
                         entity_id: t.metric,
                         state: 'N/A',
                         attributes: {},
                         last_changed: '',
                         last_updated: '',
                         display_name: attributeLabels[t.metric] || t.metric,
                         cleaned_value: t.value,
                         cleaned_ts: t.ts
                    }));
                }
            }

            entities.value = finalEntities;

        } catch (err) {
             console.error(err);
        }
    }
}

const handleToggle = async (entity: HAEntity) => {
    if (!device.value?.SourceID) return;
    
    actionLoading.value = true;
    const domain = entity.entity_id.split('.')[0];
    const service = entity.state === 'on' ? 'turn_off' : 'turn_on';
    
    try {
        await callSourceService(device.value.SourceID, {
            domain: domain,
            service: service,
            service_data: {
                entity_id: entity.entity_id
            }
        });
        Message.success('操作指令已发送');
        // Wait a bit for state to update then refresh
        setTimeout(fetchData, 1000);
    } catch (err) {
        Message.error('操作失败');
    } finally {
        actionLoading.value = false;
    }
}

const canToggle = (entity: HAEntity) => {
    const domain = entity.entity_id.split('.')[0];
    return ['switch', 'light', 'fan', 'input_boolean'].includes(domain);
}

onMounted(async () => {
    loading.value = true;
    await fetchData();
    loading.value = false;

    timer = setInterval(fetchData, 5000);
});

onUnmounted(() => {
    if(timer) clearInterval(timer);
});
</script>

<style scoped>
.page-container {
    padding: 20px;
}
.header {
    margin-bottom: 20px;
    background: var(--color-bg-2);
    padding: 10px;
    border-radius: 4px;
}
</style>

