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

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) return (n / 1_000).toFixed(1) + 'K';
  return n.toLocaleString();
}
function fmtPct(n: number): string { return (n * 100).toFixed(1) + '%'; }

function getPositionBadgeClass(pos: number): string {
  if (pos <= 10) return 'green';
  if (pos <= 14) return 'yellow';
  return 'orange';
}

function getOpportunityLabel(pos: number): string {
  if (pos <= 7) return 'Easy Win';
  if (pos <= 14) return 'Moderate';
  return 'Needs Work';
}

function getOpportunityBadgeCls(pos: number): string {
  if (pos <= 7) return 'gsc-severity-low';
  if (pos <= 14) return 'gsc-severity-medium';
  return 'gsc-severity-high';
}

export function App() {
  const [data, setData] = useState<any>((window as any).__MCP_APP_DATA__ || null);
  const [posFilter, setPosFilter] = useState('all');
  const [minImp, setMinImp] = useState(0);

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

  const filtered = useMemo(() => {
    if (!data?.opportunities) return [];
    return data.opportunities.filter((opp: any) => {
      if (posFilter === '4-10' && (opp.position < 4 || opp.position > 10)) return false;
      if (posFilter === '11-20' && (opp.position < 11 || opp.position > 20)) return false;
      if (opp.impressions < minImp) return false;
      return true;
    });
  }, [data, posFilter, minImp]);

  const totalGain = useMemo(() =>
    filtered.reduce((s: number, o: any) => s + (o.estimatedClickGain || 0), 0),
    [filtered]
  );

  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>;

  return (
    <div style={{ padding: 16 }}>
      {/* Header */}
      <div style={{ marginBottom: 24 }}>
        <h1 style={{ fontSize: 24, fontWeight: 500, marginBottom: 8 }}>Quick Wins Board</h1>
        <div style={{ display: 'flex', gap: 24, fontSize: 14, color: '#5f6368', flexWrap: 'wrap' }}>
          <span><strong style={{ color: '#1a73e8', fontWeight: 600 }}>{filtered.length}</strong> opportunities</span>
          <span>Est. <strong style={{ color: '#1a73e8', fontWeight: 600 }}>{fmtNum(totalGain)}</strong> additional clicks/month</span>
        </div>
      </div>

      {/* Filters */}
      <div className="gsc-filters">
        <div className="gsc-filter-group">
          <label htmlFor="pos-filter">Position:</label>
          <select id="pos-filter" className="gsc-select" value={posFilter} onChange={e => setPosFilter(e.target.value)}>
            <option value="all">All</option>
            <option value="4-10">4–10</option>
            <option value="11-20">11–20</option>
          </select>
        </div>
        <div className="gsc-filter-group">
          <label htmlFor="imp-filter">Min Impressions:</label>
          <input
            id="imp-filter" type="number" className="gsc-input"
            value={minImp} min={0} step={100}
            onChange={e => setMinImp(parseInt(e.target.value) || 0)}
          />
        </div>
      </div>

      {/* Cards */}
      {filtered.length === 0 ? (
        <div style={{ textAlign: 'center', padding: 48, color: '#5f6368', fontSize: 14 }}>
          No opportunities match your filters
        </div>
      ) : (
        <div className="gsc-cards-grid">
          {filtered.map((opp: any, i: number) => {
            const badgeCls = getPositionBadgeClass(opp.position);
            const impactPct = Math.min((opp.impactScore / 100) * 100, 100);
            return (
              <div key={i} className="gsc-opportunity-card">
                {/* Header row with keyword + opportunity badge */}
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
                  <div style={{ fontSize: 16, fontWeight: 600, color: '#202124', wordBreak: 'break-word' }}>
                    {opp.keyword}
                  </div>
                  <span className={`status-badge-sm ${getOpportunityBadgeCls(opp.position)}`} style={{
                    padding: '3px 8px', borderRadius: 4, fontSize: 10, fontWeight: 600, flexShrink: 0,
                  }}>
                    {getOpportunityLabel(opp.position)}
                  </span>
                </div>

                <div style={{ fontSize: 12, color: '#1a73e8', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={opp.page}>
                  {opp.page}
                </div>

                <div className="gsc-metrics-grid">
                  <div className="gsc-metric-item">
                    <div className="gsc-metric-label">Position</div>
                    <div className="gsc-metric-value">
                      <span className={`position-badge ${badgeCls}`}>#{opp.position.toFixed(1)}</span>
                    </div>
                  </div>
                  <div className="gsc-metric-item">
                    <div className="gsc-metric-label">Impressions</div>
                    <div className="gsc-metric-value">{fmtNum(opp.impressions)}</div>
                  </div>
                  <div className="gsc-metric-item">
                    <div className="gsc-metric-label">Current CTR</div>
                    <div className="gsc-metric-value">{fmtPct(opp.currentCtr)}</div>
                  </div>
                  <div className="gsc-metric-item">
                    <div className="gsc-metric-label">Impact Score</div>
                    <div className="gsc-metric-value">{opp.impactScore?.toFixed(0) ?? '—'}</div>
                  </div>
                </div>

                {/* Estimated Click Gain */}
                <div className="gsc-highlight">
                  <div className="label">Estimated Click Gain</div>
                  <div className="value">+{fmtNum(opp.estimatedClickGain)} clicks/mo</div>
                </div>

                {/* Impact Bar */}
                <div className="impact-bar">
                  <div className="impact-bar-fill" style={{ width: `${impactPct}%` }} />
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
