<template>
  <Teleport to="body">
    <div class="modal fade" id="historyModal" tabindex="-1" aria-hidden="true" ref="modalRef">
    <div class="modal-dialog modal-xl modal-dialog-centered">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title">
            <i class="fas fa-chart-area me-2" style="color: var(--accent-color);"></i>
            <span>{{ clientName }}</span>
          </h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="chart-controls">
            <div class="d-flex align-items-center gap-2">
              <label class="text-muted"><i class="far fa-clock me-1"></i> Range:</label>
              <select v-model="range" class="form-select form-select-sm" style="width: auto; min-width: 200px;"
                @change="loadHistory">
                <option value="1h">Last 1 Hour (30s agg)</option>
                <option value="3h">Last 3 Hours (1m agg)</option>
                <option value="6h">Last 6 Hours (1m agg)</option>
                <option value="12h">Last 12 Hours (1m agg)</option>
                <option value="24h">Last 24 Hours (1m agg)</option>
                <option disabled>──────────</option>
                <option value="1d">Last 1 Day (15m agg)</option>
                <option value="2d">Last 2 Days (15m agg)</option>
                <option value="3d">Last 3 Days (15m agg)</option>
                <option disabled>──────────</option>
                <option value="4d">Last 4 Days (1h agg)</option>
                <option value="5d">Last 5 Days (1h agg)</option>
                <option value="6d">Last 6 Days (1h agg)</option>
                <option value="7d">Last 7 Days (1h agg)</option>
                <option value="14d">Last 14 Days (1h agg)</option>
                <option value="30d">Last 1 Month (1h agg)</option>
              </select>
            </div>

            <div class="d-flex align-items-center gap-3 bg-white-custom px-3 py-1 border rounded">
              <span class="small fw-bold text-muted">Metric:</span>
              <div class="form-check form-switch mb-0">
                <input class="form-check-input" type="checkbox" role="switch" id="vizToggle" v-model="isSpeedMode"
                  @change="renderChart">
                <label class="form-check-label text-main" for="vizToggle">
                  {{ isSpeedMode ? 'Speed (Mbps)' : 'Data Volume' }}
                </label>
              </div>
            </div>
          </div>

          <div class="modal-chart-container">
            <canvas ref="chartCanvas"></canvas>
            <div v-if="loading" class="position-absolute top-50 start-50 translate-middle">
              <div class="spinner-border text-primary" role="status"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
    </div>
  </Teleport>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue';
import Chart from 'chart.js/auto';
import { useApi } from '../composables/useApi';
import { useFormatters } from '../composables/useFormatters';
import { Modal } from 'bootstrap';

const props = defineProps(['modelValue']); // If we wanted v-model control, but using manual open method for now
const { fetchClientHistory } = useApi();
const { parseServerDate } = useFormatters();

const modalRef = ref(null);
const chartCanvas = ref(null);
const clientName = ref('');
const range = ref('24h');
const isSpeedMode = ref(false);
const loading = ref(false);
let bsModal = null;
let chartInstance = null;
let cachedData = null;

const MAX_CHART_POINTS = 48;

const open = (name) => {
  clientName.value = name;
  range.value = '24h';
  isSpeedMode.value = false;
  bsModal?.show();
  loadHistory();
};

const close = () => {
  bsModal?.hide();
};

const loadHistory = async () => {
  if (!clientName.value) return;
  loading.value = true;
  try {
    const res = await fetchClientHistory(clientName.value, range.value);
    if (res.success && res.data.history) {
      cachedData = res.data.history;
      renderChart();
    } else {
      cachedData = [];
      if (chartInstance) chartInstance.destroy();
    }
  } catch (e) {
    console.error(e);
  } finally {
    loading.value = false;
  }
};

const renderChart = () => {
  if (!chartCanvas.value || !cachedData) return;
  if (chartInstance) chartInstance.destroy();

  const ctx = chartCanvas.value.getContext('2d');
  const downsampled = downsampleData(cachedData, MAX_CHART_POINTS);

  const labels = [];
  const dataRx = [];
  const dataTx = [];

  downsampled.forEach(point => {
    const d = parseServerDate(point.timestamp);
    let label = '';
    
    if(range.value.includes('h') || range.value === '1d') {
         label = d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    } else {
         label = d.toLocaleDateString([], { month: 'short', day: 'numeric' }) + ' ' +
                d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }
    labels.push(label);

    if (!isSpeedMode.value) {
      dataRx.push(point.bytes_received / (1024 * 1024)); // MB
      dataTx.push(point.bytes_sent / (1024 * 1024));     // MB
    } else {
      dataRx.push(point.bytes_received_rate_mbps);
      dataTx.push(point.bytes_sent_rate_mbps);
    }
  });

  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
  const gridColor = isDark ? 'rgba(240, 246, 252, 0.1)' : 'rgba(0,0,0,0.05)';
  const textColor = isDark ? '#8b949e' : '#6c757d';

  chartInstance = new Chart(ctx, {
    type: 'line',
    data: {
      labels,
      datasets: [
        {
          label: !isSpeedMode.value ? 'Received (MB)' : 'RX Mbps',
          data: dataRx,
          borderColor: '#27ae60',
          backgroundColor: 'rgba(39, 174, 96, 0.1)',
          borderWidth: 2,
          fill: true,
          tension: 0.3
        },
        {
          label: !isSpeedMode.value ? 'Sent (MB)' : 'TX Mbps',
          data: dataTx,
          borderColor: '#2980b9',
          backgroundColor: 'rgba(41, 128, 185, 0.1)',
          borderWidth: 2,
          fill: true,
          tension: 0.3
        }
      ]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      interaction: {
        mode: 'index',
        intersect: false,
      },
      plugins: {
        legend: { labels: { color: textColor } }
      },
      scales: {
        x: {
          ticks: { color: textColor, maxTicksLimit: 8 },
          grid: { color: gridColor }
        },
        y: {
          beginAtZero: true,
          ticks: { color: textColor },
          grid: { color: gridColor }
        }
      }
    }
  });
};

const downsampleData = (data, maxPoints) => {
  if (!data || data.length === 0) return [];
  if (data.length <= maxPoints) return data;

  const blockSize = Math.ceil(data.length / maxPoints);
  const result = [];

  for (let i = 0; i < data.length; i += blockSize) {
    const chunk = data.slice(i, i + blockSize);
    if (chunk.length === 0) continue;

    let sumRx = 0, sumTx = 0;
    let maxRxRate = 0, maxTxRate = 0;

    chunk.forEach(pt => {
      sumRx += (pt.bytes_received || 0);
      sumTx += (pt.bytes_sent || 0);
      maxRxRate = Math.max(maxRxRate, pt.bytes_received_rate_mbps || 0);
      maxTxRate = Math.max(maxTxRate, pt.bytes_sent_rate_mbps || 0);
    });

    result.push({
      timestamp: chunk[0].timestamp,
      bytes_received: sumRx,
      bytes_sent: sumTx,
      bytes_received_rate_mbps: maxRxRate,
      bytes_sent_rate_mbps: maxTxRate
    });
  }
  return result;
}

onMounted(() => {
  bsModal = new Modal(modalRef.value);
  
  // Clean up chart on close
  modalRef.value.addEventListener('hidden.bs.modal', () => {
    if (chartInstance) {
        chartInstance.destroy();
        chartInstance = null;
    }
  });
});

onUnmounted(() => {
  if (chartInstance) chartInstance.destroy();
});

defineExpose({ open, close });
</script>
