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 getSeverityCls(severity: string): string {
  const s = severity.toLowerCase();
  if (s === 'critical') return 'gsc-severity-critical';
  if (s === 'high') return 'gsc-severity-high';
  if (s === 'medium') return 'gsc-severity-medium';
  return 'gsc-severity-low';
}

function getRecommendation(severity: string, pageCount: number): string {
  if (severity.toLowerCase() === 'critical' || severity.toLowerCase() === 'high') {
    return pageCount > 3 ? 'Redirect' : 'Merge';
  }
  if (severity.toLowerCase() === 'medium') return 'Differentiate';
  return 'Monitor';
}

function getRecommendationCls(rec: string): string {
  if (rec === 'Redirect') return 'gsc-severity-high';
  if (rec === 'Merge') return 'gsc-severity-moderate';
  if (rec === 'Differentiate') return 'gsc-severity-medium';
  return 'gsc-severity-low';
}

const severityOrder: Record<string, number> = { critical: 4, high: 3, medium: 2, low: 1 };

export function App() {
  const [data, setData] = useState<any>((window as any).__MCP_APP_DATA__ || null);
  const [expanded, setExpanded] = useState<Set<number>>(new Set());
  const [sortBy, setSortBy] = useState('severity');

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

  const sorted = useMemo(() => {
    if (!data?.keywords) return [];
    const items = [...data.keywords];
    items.sort((a: any, b: any) => {
      if (sortBy === 'severity') {
        return (severityOrder[b.severity.toLowerCase()] || 0) - (severityOrder[a.severity.toLowerCase()] || 0);
      }
      if (sortBy === 'pages') return b.pages.length - a.pages.length;
      if (sortBy === 'impressions') return b.totalImpressions - a.totalImpressions;
      if (sortBy === 'keyword') return a.keyword.localeCompare(b.keyword);
      return 0;
    });
    return items;
  }, [data, sortBy]);

  const toggle = (idx: number) => {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(idx)) next.delete(idx); else next.add(idx);
      return next;
    });
  };

  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 }}>Keyword Cannibalization Map</h1>
        <p style={{ fontSize: 14, color: '#5f6368' }}>
          Keywords where multiple pages compete for the same ranking
        </p>
      </div>

      {/* Controls */}
      <div className="gsc-filters">
        <div className="gsc-filter-group">
          <label htmlFor="sort-by">Sort by:</label>
          <select id="sort-by" className="gsc-select" value={sortBy} onChange={e => setSortBy(e.target.value)}>
            <option value="severity">Severity</option>
            <option value="impressions">Impressions</option>
            <option value="pages">Number of Pages</option>
            <option value="keyword">Keyword</option>
          </select>
        </div>
      </div>

      {/* Table */}
      <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)',
      }}>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead style={{ background: '#f8f9fa' }}>
            <tr>
              <th style={{ textAlign: 'left', padding: '12px 16px', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', color: '#5f6368', letterSpacing: 0.5 }}>
                Keyword
              </th>
              <th style={{ textAlign: 'left', padding: '12px 16px', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', color: '#5f6368' }}>
                # Pages
              </th>
              <th style={{ textAlign: 'left', padding: '12px 16px', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', color: '#5f6368' }}>
                Impressions
              </th>
              <th style={{ textAlign: 'left', padding: '12px 16px', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', color: '#5f6368' }}>
                Severity
              </th>
              <th style={{ textAlign: 'left', padding: '12px 16px', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', color: '#5f6368' }}>
                Action
              </th>
            </tr>
          </thead>
          <tbody>
            {sorted.map((item: any, idx: number) => {
              const isExp = expanded.has(idx);
              const rec = getRecommendation(item.severity, item.pages?.length || 0);
              return (
                <React.Fragment key={idx}>
                  {/* Keyword Row */}
                  <tr
                    className="gsc-expandable-row"
                    onClick={() => toggle(idx)}
                    style={{ borderTop: '1px solid #e8eaed' }}
                  >
                    <td style={{ padding: 16, fontWeight: 500, fontSize: 14 }}>
                      <span className={`gsc-expand-icon ${isExp ? 'expanded' : ''}`}>▶</span>
                      {item.keyword}
                    </td>
                    <td style={{ padding: 16 }}>{item.pages?.length || 0}</td>
                    <td style={{ padding: 16, fontVariantNumeric: 'tabular-nums' }}>{fmtNum(item.totalImpressions)}</td>
                    <td style={{ padding: 16 }}>
                      <span className={getSeverityCls(item.severity)} style={{
                        display: 'inline-block', padding: '4px 10px', borderRadius: 4, fontSize: 12, fontWeight: 600,
                      }}>
                        {item.severity}
                      </span>
                    </td>
                    <td style={{ padding: 16 }}>
                      <span className={getRecommendationCls(rec)} style={{
                        display: 'inline-block', padding: '4px 10px', borderRadius: 4, fontSize: 12, fontWeight: 600,
                      }}>
                        {rec}
                      </span>
                    </td>
                  </tr>

                  {/* Expanded Pages */}
                  {isExp && (
                    <tr style={{ background: '#fafafa' }}>
                      <td colSpan={5} style={{ padding: '16px 16px 16px 48px', borderTop: '1px solid #e8eaed' }}>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                          {(item.pages || []).map((page: any, pi: number) => {
                            const isWinner = pi === 0;
                            const impPct = item.totalImpressions > 0
                              ? (page.impressions / item.totalImpressions) * 100 : 0;
                            return (
                              <div key={pi} className={`gsc-page-item ${isWinner ? 'winner' : ''}`}>
                                <div className="gsc-page-url">
                                  {page.url}
                                  {isWinner && <span className="winner-badge">Winner</span>}
                                </div>
                                <div className="gsc-page-metrics">
                                  <div className="gsc-metric-item">
                                    <div className="gsc-metric-label">Clicks</div>
                                    <div className="gsc-metric-value" style={{ fontSize: 14 }}>{fmtNum(page.clicks)}</div>
                                  </div>
                                  <div className="gsc-metric-item">
                                    <div className="gsc-metric-label">Impressions</div>
                                    <div className="gsc-metric-value" style={{ fontSize: 14 }}>{fmtNum(page.impressions)}</div>
                                  </div>
                                  <div className="gsc-metric-item">
                                    <div className="gsc-metric-label">CTR</div>
                                    <div className="gsc-metric-value" style={{ fontSize: 14 }}>{fmtPct(page.ctr)}</div>
                                  </div>
                                  <div className="gsc-metric-item">
                                    <div className="gsc-metric-label">Position</div>
                                    <div className="gsc-metric-value" style={{ fontSize: 14 }}>{page.position.toFixed(1)}</div>
                                  </div>
                                </div>
                                <div className="impression-bar">
                                  <div className="impression-bar-fill" style={{ width: `${impPct}%` }} />
                                </div>
                              </div>
                            );
                          })}
                        </div>
                      </td>
                    </tr>
                  )}
                </React.Fragment>
              );
            })}
          </tbody>
        </table>

        {sorted.length === 0 && (
          <div style={{ textAlign: 'center', padding: 48, color: '#5f6368', fontSize: 14 }}>
            No cannibalization data available
          </div>
        )}
      </div>
    </div>
  );
}
