import React, { useState, useMemo } from 'react';
import { useApp } from '@modelcontextprotocol/ext-apps/react';
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import { MetricCard } from '../../components/data/MetricCard';
import { DataTable } from '../../components/data/DataTable';
import { SparklineChart } from '../../components/charts/SparklineChart';
import '../../styles/base.css';
import '../../styles/gsc-theme.css';

/* ── helpers ─────────────────────────────────────────── */

function extractData(result: CallToolResult): any {
  const sc = (result as any).structuredContent;
  if (sc) return sc;
  for (const item of result.content || []) {
    if (item.type === 'text') { try { return JSON.parse(item.text); } catch {} }
  }
  return null;
}

function fmtNum(n: number): string {
  if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M';
  if (n >= 1_000) return (n / 1_000).toFixed(1) + 'K';
  return n.toLocaleString();
}

function fmtPct(n: number): string { return (n * 100).toFixed(1) + '%'; }
function fmtPos(n: number): string { return n.toFixed(1); }

function getTrend(val: number, invert = false): { dir: 'up' | 'down' | 'flat'; label: string } {
  if (val === 0) return { dir: 'flat', label: 'No change' };
  const isPositive = invert ? val < 0 : val > 0;
  return {
    dir: isPositive ? 'up' : 'down',
    label: `${Math.abs(val).toFixed(1)}%`,
  };
}

/* ── main app ────────────────────────────────────────── */

export function App() {
  const [data, setData] = useState<any>((window as any).__MCP_APP_DATA__ || null);

  const { isConnected, error } = useApp({
    appInfo: { name: 'Performance Dashboard', version: '1.0.0' },
    capabilities: {},
    onAppCreated: (app) => {
      app.ontoolresult = async (result) => {
        const parsed = extractData(result);
        if (parsed) setData(parsed);
      };
    },
  });

  /* queries table rows */
  const queryRows = useMemo(() => {
    if (!data?.topQueries) return [];
    return data.topQueries.map((q: any, i: number) => ({
      id: String(i),
      query: q.query,
      clicks: q.clicks,
      impressions: q.impressions,
      ctr: fmtPct(q.ctr),
      position: fmtPos(q.position),
      _clicks: q.clicks,
      _impressions: q.impressions,
      _ctr: q.ctr,
      _position: q.position,
    }));
  }, [data]);

  /* pages table rows */
  const pageRows = useMemo(() => {
    if (!data?.topPages) return [];
    return data.topPages.map((p: any, i: number) => ({
      id: String(i),
      page: p.page,
      clicks: p.clicks,
      impressions: p.impressions,
      ctr: fmtPct(p.ctr),
      position: fmtPos(p.position),
      _clicks: p.clicks,
      _impressions: p.impressions,
      _ctr: p.ctr,
      _position: p.position,
    }));
  }, [data]);

  /* render states */
  if (error) return <div className="error-state"><h3>Error</h3><p>{error.message}</p></div>;
  if (!isConnected) return <div className="loading-state"><div className="loading-spinner" /><p>Connecting…</p></div>;
  if (!data) return <div className="loading-state"><div className="loading-spinner" /><p>Waiting for data…</p></div>;

  const { kpis, trends, timeseries } = data;
  const clicksTrend = getTrend(trends?.clicks ?? 0);
  const impTrend = getTrend(trends?.impressions ?? 0);
  const ctrTrend = getTrend(trends?.ctr ?? 0);
  const posTrend = getTrend(trends?.position ?? 0, true); // lower position = better

  return (
    <div style={{ padding: 16 }}>
      {/* Header */}
      <div style={{ marginBottom: 24 }}>
        <h1 style={{ fontSize: 24, fontWeight: 500, marginBottom: 4 }}>{data.siteUrl || 'Performance Dashboard'}</h1>
        <div style={{ fontSize: 14, color: '#5f6368' }}>
          {data.startDate} – {data.endDate}
        </div>
      </div>

      {/* KPI Grid */}
      <div className="stats-grid stats-grid-4" style={{ marginBottom: 24 }}>
        <MetricCard
          label="Total Clicks"
          value={fmtNum(kpis?.totalClicks ?? 0)}
          trend={clicksTrend.dir}
          trendValue={clicksTrend.label}
          color="blue"
        >
          {timeseries?.clicks && (
            <div style={{ marginTop: 8, display: 'flex', justifyContent: 'center' }}>
              <SparklineChart values={timeseries.clicks} color="#1a73e8" width={100} height={28} />
            </div>
          )}
        </MetricCard>

        <MetricCard
          label="Total Impressions"
          value={fmtNum(kpis?.totalImpressions ?? 0)}
          trend={impTrend.dir}
          trendValue={impTrend.label}
          color="green"
        >
          {timeseries?.impressions && (
            <div style={{ marginTop: 8, display: 'flex', justifyContent: 'center' }}>
              <SparklineChart values={timeseries.impressions} color="#34a853" width={100} height={28} />
            </div>
          )}
        </MetricCard>

        <MetricCard
          label="Avg CTR"
          value={fmtPct(kpis?.avgCtr ?? 0)}
          trend={ctrTrend.dir}
          trendValue={ctrTrend.label}
          color="yellow"
        />

        <MetricCard
          label="Avg Position"
          value={fmtPos(kpis?.avgPosition ?? 0)}
          trend={posTrend.dir}
          trendValue={posTrend.label}
          color="purple"
        />
      </div>

      {/* Clicks Over Time chart */}
      {timeseries?.clicks && timeseries.clicks.length > 0 && (
        <div style={{
          background: 'white', padding: 20, borderRadius: 8, marginBottom: 24,
          boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08)',
        }}>
          <h2 style={{ fontSize: 16, fontWeight: 500, marginBottom: 16 }}>Clicks Over Time</h2>
          <svg width="100%" height="60" viewBox={`0 0 ${timeseries.clicks.length * 8} 60`} preserveAspectRatio="none">
            <polyline
              points={timeseries.clicks.map((v: number, i: number) => {
                const max = Math.max(...timeseries.clicks);
                const min = Math.min(...timeseries.clicks);
                const range = max - min || 1;
                const x = (i / (timeseries.clicks.length - 1)) * (timeseries.clicks.length * 8);
                const y = 60 - ((v - min) / range) * 60;
                return `${x},${y}`;
              }).join(' ')}
              fill="none" stroke="#1a73e8" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
            />
          </svg>
        </div>
      )}

      {/* Top Queries Table */}
      <div style={{ marginBottom: 24 }}>
        <div style={{
          background: 'white', borderRadius: 8, overflow: 'hidden',
          boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08)',
        }}>
          <div style={{ padding: '12px 16px', borderBottom: '1px solid #e8eaed' }}>
            <h2 style={{ fontSize: 16, fontWeight: 500 }}>Top Queries</h2>
          </div>
          <DataTable
            columns={[
              { key: 'query', label: 'Query', sortable: true },
              { key: 'clicks', label: 'Clicks', sortable: true, format: 'number' },
              { key: 'impressions', label: 'Impressions', sortable: true, format: 'number' },
              { key: 'ctr', label: 'CTR', sortable: true, format: 'percent' },
              { key: 'position', label: 'Position', sortable: true, format: 'number' },
            ]}
            rows={queryRows}
            pageSize={10}
            emptyMessage="No query data available"
          />
        </div>
      </div>

      {/* Top Pages Table */}
      <div style={{ marginBottom: 24 }}>
        <div style={{
          background: 'white', borderRadius: 8, overflow: 'hidden',
          boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08)',
        }}>
          <div style={{ padding: '12px 16px', borderBottom: '1px solid #e8eaed' }}>
            <h2 style={{ fontSize: 16, fontWeight: 500 }}>Top Pages</h2>
          </div>
          <DataTable
            columns={[
              { key: 'page', label: 'Page', sortable: true, format: 'url' },
              { key: 'clicks', label: 'Clicks', sortable: true, format: 'number' },
              { key: 'impressions', label: 'Impressions', sortable: true, format: 'number' },
              { key: 'ctr', label: 'CTR', sortable: true, format: 'percent' },
              { key: 'position', label: 'Position', sortable: true, format: 'number' },
            ]}
            rows={pageRows}
            pageSize={10}
            emptyMessage="No page data available"
          />
        </div>
      </div>
    </div>
  );
}
