import React, { useState, useEffect } from 'react';
import axios from 'axios';

// Simple logging utilities
const log = (...args) => console.log('[RulesTab]', ...args);
const warn = (...args) => console.warn('[RulesTab]', ...args);
const error = (...args) => console.error('[RulesTab]', ...args);

const RULE_LABELS = new Set(['Type', 'Use', 'Roll', 'Action']);

const splitHighlightedText = (text, query) => {
  const value = String(text || '');
  const term = String(query || '').trim();
  if (!term) return [value];
  const regex = new RegExp(`(${term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
  return value.split(regex).filter(part => part !== '').map((part, index) => (
    part.toLowerCase() === term.toLowerCase()
      ? <mark key={`${part}-${index}`} className="rounded bg-yellow-200 px-0.5 text-black">{part}</mark>
      : part
  ));
};

const parseRuleLines = (content) => String(content || '')
  .split('\n')
  .map(line => line.trim())
  .filter(Boolean)
  .map(line => {
    const match = line.match(/^([A-Za-z ]{2,18}):\s*(.*)$/);
    if (!match || !RULE_LABELS.has(match[1])) return { label: null, text: line };
    return { label: match[1], text: match[2] };
  });

function RuleContent({ content, query, compact = false }) {
  const lines = parseRuleLines(content || 'No content available.');
  const visibleLines = compact ? lines.slice(0, 3) : lines;
  const hiddenCount = Math.max(0, lines.length - visibleLines.length);

  return (
    <div className={compact ? 'space-y-1.5' : 'space-y-2'}>
      {visibleLines.map((line, index) => (
        <div
          key={`${line.label || 'line'}-${index}`}
          className={line.label
            ? 'grid gap-1 rounded border border-slate-700 bg-slate-900/60 p-2 sm:grid-cols-[5.5rem_1fr]'
            : 'rounded border border-slate-700 bg-slate-900/40 p-2 leading-relaxed'}
        >
          {line.label ? (
            <>
              <span className="text-xs font-semibold uppercase tracking-wide text-blue-300">{line.label}</span>
              <span className="text-slate-100">{splitHighlightedText(line.text, query)}</span>
            </>
          ) : (
            <span className="text-slate-100">{splitHighlightedText(line.text, query)}</span>
          )}
        </div>
      ))}
      {compact && hiddenCount > 0 && (
        <div className="text-xs text-slate-400">+{hiddenCount} more line{hiddenCount === 1 ? '' : 's'}</div>
      )}
    </div>
  );
}

function RuleExample({ example, query, compact = false }) {
  if (!example) return null;
  const text = compact && example.length > 180 ? `${example.slice(0, 180).replace(/\s+\S*$/, '')}...` : example;
  return (
    <div className={compact ? 'mt-2 rounded border border-amber-500/25 bg-amber-950/20 p-2' : 'mt-4 rounded border border-amber-500/30 bg-amber-950/20 p-3'}>
      <div className="mb-1 text-xs font-semibold uppercase tracking-wide text-amber-200">Example</div>
      <div className="text-slate-100">{splitHighlightedText(text, query)}</div>
    </div>
  );
}

function RulesTab({ authedPlayer, sessionId }) {
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState([]);
  const [recentSearches, setRecentSearches] = useState([]);
  const [selectedCategory, setSelectedCategory] = useState('all');
  const [loading, setLoading] = useState(false);
  const [selectedRule, setSelectedRule] = useState(null);
  const [browseCount, setBrowseCount] = useState(20);

  // Categories - load from backend when available so users can browse
  const [ruleCategories, setRuleCategories] = useState([
    { id: 'all', name: 'All Rules' }
  ]);

  const buildHeaders = () => {
    const headers = { 'x-session-id': sessionId || '' };
    if (authedPlayer === 'gm') headers['x-gm-secret'] = process.env.REACT_APP_GM_SECRET || 'defaultsecret';
    return headers;
  };

  useEffect(() => {
    // fetch categories from backend; fallback to defaults if not available
    (async () => {
      try {
        const resp = await axios.get('/api/rules/categories', { headers: buildHeaders() });
        if (resp && Array.isArray(resp.data) && resp.data.length) {
          setRuleCategories(resp.data);
        }
      } catch (e) {
        log('Could not fetch categories, using defaults', e && e.message);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Popular/Quick access rules tuned for live play
  const quickRules = [
    'Dodge',
    'Parry',
    'Full Auto Burst',
    'Semi-Auto Burst',
    'Suppressing Fire',
    'Overwatch',
    'Pinning',
    'Righteous Fury',
    'Critical Damage',
    'Hordes',
    'Fear',
    'Cohesion Damage',
    'Maintaining Squad Mode',
    'Requisition',
    'Renown'
  ];

  const midgameCategories = [
    { id: 'actions', name: 'Actions' },
    { id: 'combat', name: 'Combat' },
    { id: 'damage', name: 'Damage' },
    { id: 'conditions', name: 'Conditions' },
    { id: 'hordes', name: 'Hordes' },
    { id: 'psychic', name: 'Psychic' },
    { id: 'skills', name: 'Skills' },
    { id: 'talents', name: 'Talents' },
    { id: 'squad_mode', name: 'Squad/Cohesion' },
    { id: 'requisition', name: 'Req/Renown' },
    { id: 'gm_tables', name: 'GM Tables' }
  ];

  useEffect(() => {
    loadRecentSearches();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const loadRecentSearches = () => {
    const saved = localStorage.getItem('dw:rules:recent');
    if (saved) {
      try {
        setRecentSearches(JSON.parse(saved));
      } catch (e) {
        warn('Failed to load recent searches:', e);
      }
    }
  };

  const saveRecentSearch = (query) => {
    const updated = [query, ...recentSearches.filter(q => q !== query)].slice(0, 10);
    setRecentSearches(updated);
    localStorage.setItem('dw:rules:recent', JSON.stringify(updated));
  };

  const searchRules = async (query, category = selectedCategory) => {
    if (!query.trim()) return;

    setLoading(true);
    try {
      log('Searching rules:', query, 'category:', category);
      
      const params = new URLSearchParams({
        q: query.trim(),
        category: category !== 'all' ? category : '',
        midgame: 'true',
        limit: '30'
      });

      const response = await axios.get(`/api/rules/search?${params}`, {
        headers: buildHeaders()
      });

      if (response.data && Array.isArray(response.data)) {
        setSearchResults(response.data);
        saveRecentSearch(query.trim());
      } else {
        setSearchResults([]);
        warn('No search results returned');
      }
    } catch (err) {
      error('Search failed:', err);
      setSearchResults([]);
      
      // Fallback - show some example results
      setSearchResults([
        {
          id: 'example_1',
          title: 'Rules Search Not Available',
          content: 'The rules database is not yet populated. This feature requires processing the PDF rulebooks.',
          category: 'system',
          page: null,
          source: 'System'
        }
      ]);
    } finally {
      setLoading(false);
    }
  };

  const handleSearch = (e) => {
    e.preventDefault();
    searchRules(searchQuery);
  };

  const handleQuickSearch = (rule) => {
    setSearchQuery(rule);
    searchRules(rule);
  };

  const handleCategoryChange = (category) => {
    setSelectedCategory(category);
    if (searchQuery.trim()) {
      searchRules(searchQuery, category);
    }
  };

  // Fetch full rule content when opening modal
  const openRule = async (rule) => {
    setSelectedRule(rule); // show immediately with truncated content
    try {
      const resp = await axios.get(`/api/rules/rule/${rule.rule_id || rule.id}`, { headers: buildHeaders() });
      if (resp && resp.data && resp.data.content) {
        setSelectedRule(prev => prev ? { ...prev, ...resp.data } : resp.data);
      }
    } catch (e) {
      warn('Could not fetch full rule:', e && e.message);
    }
  };

  // Fetch random rules for a category (shared helper)
  const fetchRandom = async (category, count = browseCount) => {
    setLoading(true);
    try {
      const params = new URLSearchParams({ count: String(count), category: category !== 'all' ? category : '', midgame: 'true' });
      const resp = await axios.get(`/api/rules/random?${params}`, { headers: buildHeaders() });
      if (resp && Array.isArray(resp.data)) setSearchResults(resp.data);
    } catch (e) {
      warn('Browse failed', e && e.message);
      setSearchResults([]);
    } finally {
      setLoading(false);
    }
  };

  // ...existing code... (buildHeaders already declared earlier)

  return (
    <section className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-slate-100 p-4 md:p-8">
      <div className="mx-auto max-w-7xl space-y-6">
        {/* Header */}
        <div className="text-center">
          <h1 className="text-3xl font-bold mb-2">Deathwatch Rules</h1>
          <p className="text-slate-300">Search and reference rules from the Core Rulebook and GM's Kit</p>
        </div>

        {/* Search Section */}
        <div className="bg-slate-800 rounded-xl p-6 border border-slate-600">
          <form onSubmit={handleSearch} className="space-y-4">
            <div className="flex gap-4">
              <div className="flex-1">
                <input
                  type="text"
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  placeholder="Search for rules, weapons, talents, skills..."
                  className="w-full px-4 py-2 rounded-lg border border-slate-600 bg-slate-800 text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500"
                />
              </div>
              <select
                value={selectedCategory}
                onChange={(e) => handleCategoryChange(e.target.value)}
                className="px-4 py-2 rounded-lg border border-slate-600 bg-slate-800 text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
              >
                {ruleCategories.map(cat => (
                  <option key={cat.id} value={cat.id} className="bg-slate-800">
                    {cat.name}
                  </option>
                ))}
              </select>
              <div className="flex items-center gap-2">
                <button
                  type="submit"
                  disabled={loading || !searchQuery.trim()}
                  className="px-6 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-lg font-medium transition-colors"
                >
                  {loading ? 'Searching...' : 'Search'}
                </button>
                <button
                  type="button"
                  onClick={async () => {
	                    setLoading(true);
	                    try {
	                      const params = new URLSearchParams({ count: '20', category: selectedCategory !== 'all' ? selectedCategory : '', midgame: 'true' });
	                      const resp = await axios.get(`/api/rules/random?${params}`, { headers: buildHeaders() });
                      if (resp && Array.isArray(resp.data)) setSearchResults(resp.data);
                    } catch (e) {
                      warn('Browse failed', e && e.message);
                    } finally {
                      setLoading(false);
                    }
                  }}
                  className="px-4 py-2 bg-green-600 hover:bg-green-700 rounded-lg font-medium transition-colors"
                >
                  Browse
                </button>
              </div>
            </div>
          </form>

          {/* Quick Rules */}
          <div className="mt-6">
            <h3 className="text-lg font-semibold mb-3">Midgame Reference</h3>
            <div className="flex flex-wrap gap-2">
              {quickRules.map(rule => (
                <button
                  key={rule}
                  onClick={() => handleQuickSearch(rule)}
                  className="px-3 py-1 text-sm bg-slate-800 hover:bg-slate-700 rounded-md border border-slate-600 transition-colors"
                >
                  {rule}
                </button>
              ))}
            </div>
          </div>

          <div className="mt-6">
            <h3 className="text-lg font-semibold mb-3">Table Situations</h3>
            <div className="flex flex-wrap gap-2">
              {midgameCategories.map(cat => (
                <button
                  key={cat.id}
                  onClick={async () => {
                    setSelectedCategory(cat.id);
                    await fetchRandom(cat.id, 12);
                  }}
                  className="px-3 py-1 text-sm bg-slate-700 hover:bg-slate-600 rounded-md border border-slate-500 transition-colors"
                >
                  {cat.name}
                </button>
              ))}
            </div>
          </div>

          {/* Category Buttons - quick browse */}
          <div className="mt-6">
            <h3 className="text-lg font-semibold mb-3">Browse by Category</h3>
            <div className="flex flex-wrap gap-2">
              {ruleCategories.map(cat => (
                <button
                  key={cat.id}
                  onClick={async () => {
                    const cid = cat.id;
                    setSelectedCategory(cid);
                    await fetchRandom(cid, browseCount);
                  }}
                  className={`px-3 py-1 text-sm rounded-md border transition-colors ${selectedCategory === cat.id ? 'bg-blue-500 text-white border-blue-600' : 'bg-slate-800 text-white border-slate-600 hover:bg-slate-700'}`}
                >
                  {cat.name}
                </button>
              ))}
            </div>
          </div>

          {/* Recent Searches */}
          {recentSearches.length > 0 && (
            <div className="mt-4">
              <h4 className="text-md font-medium mb-2">Recent Searches</h4>
              <div className="flex flex-wrap gap-2">
                {recentSearches.map((query, index) => (
                  <button
                    key={index}
                    onClick={() => handleQuickSearch(query)}
                    className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-800 rounded border border-slate-600 transition-colors"
                  >
                    {query}
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>

        {/* Search Results */}
        {searchResults.length > 0 && (
          <div className="bg-slate-800 rounded-xl p-6 border border-slate-600">
            <h2 className="text-xl font-semibold mb-4">
              Search Results ({searchResults.length})
            </h2>
            
            <div className="space-y-4">
              {searchResults.map((rule, index) => (
                <div
                  key={rule.id || index}
                  className="bg-slate-800 rounded-lg p-4 border border-slate-600 hover:bg-slate-800 transition-colors cursor-pointer"
                  onClick={() => openRule(rule)}
                >
                  <div className="flex justify-between items-start mb-2">
                    <h3 className="text-lg font-medium text-blue-300">{rule.title}</h3>
                    <div className="flex gap-2 text-xs">
                      {rule.category && (
                        <span className="px-2 py-1 bg-blue-700 rounded">{rule.category}</span>
                      )}
                      {rule.page && (
                        <span className="px-2 py-1 bg-green-700 rounded">p.{rule.page}</span>
                      )}
                      {rule.source && (
                        <span className="px-2 py-1 bg-purple-700 rounded">{rule.sourceAbbr || rule.source}</span>
                      )}
                      {rule.sourceMethod && (
                        <span className="px-2 py-1 bg-slate-700 rounded">{rule.sourceMethod}</span>
                      )}
                      {rule.confidence != null && (
                        <span className="px-2 py-1 bg-slate-700 rounded">{Math.round(Number(rule.confidence) * 100)}%</span>
                      )}
                    </div>
                  </div>
                  {rule.summary && (
                    <p className="text-slate-200 text-sm mb-2">{rule.summary}</p>
                  )}
                  
                  <div className="text-sm">
                    <RuleContent content={rule.content} query={searchQuery} compact />
                    <RuleExample example={rule.examples} query={searchQuery} compact />
                  </div>
                </div>
              ))}
            </div>

            {/* Show more for browse results */}
            <div className="mt-4 flex justify-center">
              <button
                onClick={async () => {
                  const next = browseCount + 20;
                  setBrowseCount(next);
                  await fetchRandom(selectedCategory, next);
                }}
                className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 rounded-md text-white"
              >
                Show more
              </button>
            </div>
          </div>
        )}

        {/* Rule Detail Modal */}
        {selectedRule && (
          <div className="fixed inset-0 bg-black flex items-center justify-center p-4 z-50">
            <div className="bg-slate-800 rounded-xl p-6 max-w-4xl max-h-[80vh] overflow-y-auto border border-slate-600">
              <div className="flex justify-between items-start mb-4">
                <h2 className="text-2xl font-bold text-blue-300">{selectedRule.title}</h2>
                <button
                  onClick={() => setSelectedRule(null)}
                  className="text-slate-400 hover:text-white text-xl"
                >
                  ×
                </button>
              </div>
              
              <div className="flex gap-2 mb-4 text-xs">
                {selectedRule.category && (
                  <span className="px-2 py-1 bg-blue-700 rounded">{selectedRule.category}</span>
                )}
                {selectedRule.page && (
                  <span className="px-2 py-1 bg-green-700 rounded">Page {selectedRule.page}{selectedRule.pageEnd && selectedRule.pageEnd !== selectedRule.page ? `-${selectedRule.pageEnd}` : ''}</span>
                )}
                {selectedRule.source && (
                  <span className="px-2 py-1 bg-purple-700 rounded">{selectedRule.sourceAbbr || selectedRule.source}</span>
                )}
                {selectedRule.sourceMethod && (
                  <span className="px-2 py-1 bg-slate-700 rounded">{selectedRule.sourceMethod}</span>
                )}
                {selectedRule.confidence != null && (
                  <span className="px-2 py-1 bg-slate-700 rounded">Confidence {Math.round(Number(selectedRule.confidence) * 100)}%</span>
                )}
              </div>
              {selectedRule.summary && (
                <p className="mb-4 text-slate-100">{selectedRule.summary}</p>
              )}
              
              <RuleContent content={selectedRule.content} query={searchQuery} />
              <RuleExample example={selectedRule.examples} query={searchQuery} />
              
              {selectedRule.relatedRules && selectedRule.relatedRules.length > 0 && (
                <div className="mt-4">
                  <h4 className="font-semibold mb-2 text-yellow-300">Related Rules:</h4>
                  <div className="flex flex-wrap gap-2">
                    {selectedRule.relatedRules.map((related, index) => (
                      <button
                        key={index}
                        onClick={() => handleQuickSearch(related)}
                        className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-700 rounded border border-slate-600 transition-colors"
                      >
                        {related}
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </div>
          </div>
        )}

        {/* No Results */}
        {searchQuery && !loading && searchResults.length === 0 && (
          <div className="bg-slate-800 rounded-xl p-6 border border-slate-600 text-center">
            <p className="text-slate-400">No rules found for "{searchQuery}"</p>
            <p className="text-xs text-slate-500 mt-2">Try different keywords or check a different category</p>
          </div>
        )}
      </div>
    </section>
  );
}

export default RulesTab;
