import { useEffect, useRef } from 'react'
import { useStore } from '@nanostores/react'
import { Chart, LineController, LineElement, PointElement, LinearScale, CategoryScale, Filler, Tooltip } from 'chart.js'
import { $analytics, $days } from '../stores/analytics'
import { BreakdownList, AnalyticsPageSkeleton, EmptyState, PageHeader } from '../components/shared'
import { Tabs } from '../components/ui'
import { Icons, getReferrerIcon, getCountryFlagUrl, getBrowserIcon, getDeviceIcon, getOSIcon } from '../components/shared/Icons'

Chart.register(LineController, LineElement, PointElement, LinearScale, CategoryScale, Filler, Tooltip)

const periodTabs = [
  { value: '7', label: '7d' },
  { value: '30', label: '30d' },
  { value: '90', label: '90d' },
]

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`
}

function formatChange(change: number): { text: string; positive: boolean } {
  const sign = change >= 0 ? '+' : ''
  return {
    text: `${sign}${change.toFixed(1)}%`,
    positive: change >= 0,
  }
}

export default function AnalyticsPage() {
  const { data, error } = useStore($analytics)
  const days = useStore($days)
  const chartRef = useRef<HTMLCanvasElement>(null)
  const chartInstance = useRef<Chart | null>(null)
  const prevDataRef = useRef(data)

  useEffect(() => {
    if (!data?.views_by_day?.length || !chartRef.current) return

    if (chartInstance.current) {
      chartInstance.current.destroy()
    }

    const ctx = chartRef.current.getContext('2d')
    if (!ctx) return

    const sortedData = [...data.views_by_day].sort((a, b) => a.date.localeCompare(b.date))

    const fontFamily = '"SF Mono", "JetBrains Mono", "Fira Code", Consolas, monospace'

    chartInstance.current = new Chart(ctx, {
      type: 'line',
      data: {
        labels: sortedData.map(d => new Date(d.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })),
        datasets: [{
          data: sortedData.map(d => d.views),
          borderColor: '#10b981',
          backgroundColor: 'rgba(16, 185, 129, 0.08)',
          borderWidth: 2,
          fill: true,
          tension: 0.3,
          pointRadius: 3,
          pointBackgroundColor: '#10b981',
          pointBorderColor: '#10b981',
          pointHoverRadius: 6,
          pointHoverBackgroundColor: '#10b981',
          pointHoverBorderColor: '#ffffff',
          pointHoverBorderWidth: 2,
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        interaction: {
          intersect: false,
          mode: 'index',
        },
        plugins: {
          tooltip: {
            backgroundColor: '#0a0a0a',
            titleColor: '#fafafa',
            bodyColor: '#fafafa',
            titleFont: { family: fontFamily, size: 11 },
            bodyFont: { family: fontFamily, size: 12 },
            padding: 10,
            cornerRadius: 0,
            displayColors: false,
            callbacks: {
              label: (ctx) => `${(ctx.parsed.y ?? 0).toLocaleString()} views`
            }
          }
        },
        scales: {
          x: {
            grid: { display: false },
            border: { display: false },
            ticks: {
              color: '#737373',
              font: { family: fontFamily, size: 10 },
              padding: 8,
              maxRotation: 0,
            }
          },
          y: {
            grid: { color: '#e5e5e5' },
            border: { display: false },
            ticks: {
              color: '#737373',
              font: { family: fontFamily, size: 10 },
              padding: 12,
            },
            beginAtZero: true
          }
        }
      }
    })

    return () => {
      if (chartInstance.current) {
        chartInstance.current.destroy()
      }
    }
  }, [data])

  // Keep previous data while loading to prevent flickering
  if (data) {
    prevDataRef.current = data
  }
  const displayData = data || prevDataRef.current

  if (error && !displayData) return <EmptyState Icon={Icons.AlertCircle} title="Failed to load analytics" description={error.message} />
  if (!displayData) return <AnalyticsPageSkeleton />

  const change = formatChange(displayData.views_change)

  return (
    <div>
      <PageHeader>
        <Tabs
          value={String(days)}
          onChange={(v) => $days.set(Number(v))}
          tabs={periodTabs}
        />
      </PageHeader>

      {/* Panel container - full-bleed borders */}
      <div className="-mx-6 lg:-mx-10 mt-6">
        {/* Stats row - 4 columns on lg, 2 on mobile */}
        <div className="relative">
          {/* Vertical dividers at column boundaries (lg: 4 cols, mobile: 2 cols) */}
          <div className="absolute top-0 bottom-0 left-1/2 border-l border-border lg:hidden" />
          <div className="hidden lg:block absolute top-0 bottom-0 border-l border-border" style={{ left: '25%' }} />
          <div className="hidden lg:block absolute top-0 bottom-0 border-l border-border" style={{ left: '50%' }} />
          <div className="hidden lg:block absolute top-0 bottom-0 border-l border-border" style={{ left: '75%' }} />

          <div className="grid grid-cols-2 lg:grid-cols-4">
            <div className="py-5 pl-6 lg:pl-10 pr-6">
              <div className="text-xs text-muted mb-1">Total Views</div>
              <div className="text-2xl font-semibold tracking-tight">{displayData.total_views.toLocaleString()}</div>
              <div className={`text-xs mt-1 ${change.positive ? 'text-success' : 'text-danger'}`}>
                {change.text} vs last period
              </div>
            </div>
            <div className="py-5 px-6 lg:pr-6">
              <div className="text-xs text-muted mb-1">Page Views</div>
              <div className="text-2xl font-semibold tracking-tight">{displayData.total_page_views.toLocaleString()}</div>
            </div>
            <div className="py-5 px-6 lg:pl-6 border-t border-border lg:border-t-0">
              <div className="text-xs text-muted mb-1">Unique Visitors</div>
              <div className="text-2xl font-semibold tracking-tight">{displayData.unique_visitors.toLocaleString()}</div>
            </div>
            <div className="py-5 pr-6 lg:pr-10 pl-6 border-t border-border lg:border-t-0">
              <div className="text-xs text-muted mb-1">Bandwidth</div>
              <div className="text-2xl font-semibold tracking-tight">{formatBytes(displayData.total_bandwidth)}</div>
            </div>
          </div>
        </div>

        {/* Horizontal divider */}
        <div className="border-t border-border" />

        {/* Chart section */}
        {displayData.views_by_day.length > 0 && (
          <>
            <div className="px-6 lg:px-10 py-6">
              <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Views Over Time</div>
              <div className="h-48">
                <canvas ref={chartRef} />
              </div>
            </div>
            <div className="border-t border-border" />
          </>
        )}

        {/* Breakdown sections - 2 columns */}
        <div className="relative">
          {/* Vertical divider at center on lg */}
          <div className="hidden lg:block absolute top-0 bottom-0 left-1/2 border-l border-border" />

          <div className="grid lg:grid-cols-2">
            {/* Top Pages */}
            {displayData.top_pages.length > 0 && (
              <div className="py-6 pl-6 lg:pl-10 pr-6 border-b border-border lg:border-b-0">
                <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Top Pages</div>
                <BreakdownList
                  items={displayData.top_pages.map(p => ({
                    label: p.path,
                    value: p.views,
                    percentage: (p.views / displayData.total_page_views) * 100,
                  }))}
                />
              </div>
            )}

            {/* Top Referrers */}
            {displayData.top_referrers.length > 0 && (
              <div className="py-6 pr-6 lg:pr-10 pl-6 border-b border-border lg:border-b-0">
                <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Top Referrers</div>
                <BreakdownList
                  items={displayData.top_referrers.map(r => {
                    const label = r.referrer || 'Direct'
                    return {
                      label,
                      value: r.views,
                      percentage: (r.views / displayData.total_views) * 100,
                      Icon: getReferrerIcon(label),
                    }
                  })}
                />
              </div>
            )}
          </div>
        </div>

        {/* Row 2: Browsers & Devices */}
        {(displayData.browsers.length > 0 || displayData.devices.length > 0) && (
          <>
            <div className="border-t border-border" />
            <div className="relative">
              <div className="hidden lg:block absolute top-0 bottom-0 left-1/2 border-l border-border" />
              <div className="grid lg:grid-cols-2">
                {displayData.browsers.length > 0 && (
                  <div className="py-6 pl-6 lg:pl-10 pr-6 border-b border-border lg:border-b-0">
                    <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Browsers</div>
                    <BreakdownList
                      items={displayData.browsers.map(b => ({
                        label: b.name,
                        value: b.count,
                        percentage: (b.count / displayData.unique_visitors) * 100,
                        Icon: getBrowserIcon(b.name) || undefined,
                      }))}
                    />
                  </div>
                )}

                {displayData.devices.length > 0 && (
                  <div className="py-6 pr-6 lg:pr-10 pl-6 border-b border-border lg:border-b-0">
                    <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Devices</div>
                    <BreakdownList
                      items={displayData.devices.map(d => ({
                        label: d.name,
                        value: d.count,
                        percentage: (d.count / displayData.unique_visitors) * 100,
                        Icon: getDeviceIcon(d.name) || undefined,
                      }))}
                    />
                  </div>
                )}
              </div>
            </div>
          </>
        )}

        {/* Row 3: Countries & OS */}
        {(displayData.countries.length > 0 || displayData.os.length > 0) && (
          <>
            <div className="border-t border-border" />
            <div className="relative">
              <div className="hidden lg:block absolute top-0 bottom-0 left-1/2 border-l border-border" />
              <div className="grid lg:grid-cols-2">
                {displayData.countries.length > 0 && (
                  <div className="py-6 pl-6 lg:pl-10 pr-6 border-b border-border lg:border-b-0">
                    <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Countries</div>
                    <BreakdownList
                      items={displayData.countries.map(c => ({
                        label: c.name,
                        value: c.count,
                        percentage: (c.count / displayData.unique_visitors) * 100,
                        flagUrl: getCountryFlagUrl(c.name, 40) || undefined,
                      }))}
                    />
                  </div>
                )}

                {displayData.os.length > 0 && (
                  <div className="py-6 pr-6 lg:pr-10 pl-6">
                    <div className="text-xs font-medium text-muted uppercase tracking-wide mb-4">Operating Systems</div>
                    <BreakdownList
                      items={displayData.os.map(o => ({
                        label: o.name,
                        value: o.count,
                        percentage: (o.count / displayData.unique_visitors) * 100,
                        Icon: getOSIcon(o.name) || undefined,
                      }))}
                    />
                  </div>
                )}
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  )
}
