import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Panel } from '../UI/Panel';
import { Badge } from '../UI/Badge';
import { Select } from '../UI/Select';
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

const DATE_RANGES = [
  { value: 'today', label: 'Сегодня' },
  { value: '7d', label: '7 дней' },
  { value: '30d', label: '30 дней' },
  { value: 'all', label: 'Всё время' },
];

const ERROR_TONES = {
  Error: 'danger',
  TypeError: 'warning',
  ReferenceError: 'warning',
  SyntaxError: 'danger',
  RangeError: 'warning',
  NetworkError: 'info',
  UnhandledRejection: 'danger',
  Warning: 'warning',
};

function formatLogEntry(e) {
  const ts = e.created_at ? new Date(e.created_at).toISOString() : 'NO_TIMESTAMP';
  const lines = [
    `[${ts}] ${e.error_type || 'Unknown'}: ${e.message || 'No message'}`,
    `  URL: ${e.url || '-'}`,
    `  Component: ${e.component || '-'}`,
    `  Line: ${e.line_number ?? '-'}:${e.column_number ?? '-'}`,
  ];
  if (e.user_id) lines.push(`  User: ${e.user_id}`);
  if (e.props) lines.push(`  Props: ${e.props}`);
  if (e.stack) {
    lines.push('  Stack:');
    e.stack.split('\n').forEach(l => lines.push('    ' + l));
  }
  lines.push(`  UA: ${e.user_agent || '-'}`);
  return lines.join('\n');
}

export default function ErrorLogPanel() {
  const [errors, setErrors] = useState([]);
  const [loading, setLoading] = useState(true);
  const [fetchError, setFetchError] = useState(null);
  const [expandedId, setExpandedId] = useState(null);
  const [filterType, setFilterType] = useState('');
  const [filterRange, setFilterRange] = useState('7d');
  const [availableTypes, setAvailableTypes] = useState([]);
  const [selected, setSelected] = useState(new Set());
  const [copied, setCopied] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const intervalRef = useRef(null);
  const client = createClient(supabaseUrl, supabaseAnonKey);

  const getRangeStart = (range) => {
    const now = new Date();
    switch (range) {
      case 'today': return new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
      case '7d': return new Date(now.getTime() - 7 * 86400000).toISOString();
      case '30d': return new Date(now.getTime() - 30 * 86400000).toISOString();
      default: return null;
    }
  };

  const fetchErrors = useCallback(async () => {
    setFetchError(null);
    let query = client.from('client_error_logs').select('*').order('created_at', { ascending: false });
    const rangeStart = getRangeStart(filterRange);
    if (rangeStart) query = query.gte('created_at', rangeStart);
    if (filterType) query = query.eq('error_type', filterType);
    const { data, error: err } = await query;
    if (err) { setFetchError(err.message); setErrors([]); }
    else {
      setErrors(data || []);
      const types = [...new Set((data || []).map((e) => e.error_type).filter(Boolean))].sort();
      setAvailableTypes(types);
    }
    setLoading(false);
  }, [filterRange, filterType]);

  useEffect(() => { setLoading(true); fetchErrors(); }, [fetchErrors]);

  useEffect(() => {
    if (intervalRef.current) clearInterval(intervalRef.current);
    intervalRef.current = setInterval(fetchErrors, 30000);
    return () => { if (intervalRef.current) clearInterval(intervalRef.current); };
  }, [fetchErrors]);

  const fmtDate = (iso) => iso ? new Date(iso).toLocaleString('ru-RU') : '—';
  const trunc = (s, n) => !s ? '—' : s.length > n ? s.slice(0, n) + '…' : s;

  const toggleSelect = (id) => {
    setSelected(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selected.size === errors.length) {
      setSelected(new Set());
    } else {
      setSelected(new Set(errors.map(e => e.id)));
    }
  };

  const handleCopyAll = async () => {
    const text = errors.map(formatLogEntry).join('\n\n');
    try { await navigator.clipboard.writeText(text); }
    catch {
      const ta = document.createElement('textarea');
      ta.value = text; document.body.appendChild(ta); ta.select();
      document.execCommand('copy'); document.body.removeChild(ta);
    }
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const handleCopySelected = async () => {
    const text = errors.filter(e => selected.has(e.id)).map(formatLogEntry).join('\n\n');
    if (!text) return;
    try { await navigator.clipboard.writeText(text); }
    catch {
      const ta = document.createElement('textarea');
      ta.value = text; document.body.appendChild(ta); ta.select();
      document.execCommand('copy'); document.body.removeChild(ta);
    }
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const handleDeleteSelected = async () => {
    if (selected.size === 0) return;
    if (!confirm(`Удалить ${selected.size} записей?`)) return;
    setDeleting(true);
    const { error: err } = await client
      .from('client_error_logs')
      .delete()
      .in('id', Array.from(selected));
    if (err) { setFetchError('Ошибка удаления: ' + err.message); }
    else { setSelected(new Set()); fetchErrors(); }
    setDeleting(false);
  };

  const handleDeleteAll = async () => {
    if (!confirm('Удалить ВСЕ записи об ошибках? Это необратимо.')) return;
    setDeleting(true);
    const { error: err } = await client
      .from('client_error_logs')
      .delete()
      .neq('id', '00000000-0000-0000-0000-000000000000');
    if (err) { setFetchError('Ошибка удаления: ' + err.message); }
    else { setSelected(new Set()); fetchErrors(); }
    setDeleting(false);
  };

  const handleDeleteOne = async (id) => {
    if (!confirm('Удалить эту запись?')) return;
    setDeleting(true);
    const { error: err } = await client
      .from('client_error_logs')
      .delete()
      .eq('id', id);
    if (err) { setFetchError('Ошибка удаления: ' + err.message); }
    else { setExpandedId(null); fetchErrors(); }
    setDeleting(false);
  };

  const downloadJSON = () => {
    const data = selected.size > 0
      ? errors.filter(e => selected.has(e.id))
      : errors;
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `errors_${new Date().toISOString().slice(0, 10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const downloadCSV = () => {
    const data = selected.size > 0
      ? errors.filter(e => selected.has(e.id))
      : errors;
    const headers = ['created_at', 'error_type', 'message', 'url', 'component', 'line_number', 'column_number', 'user_id', 'stack', 'props', 'user_agent'];
    const escape = (v) => {
      const s = v == null ? '' : String(v);
      if (s.includes(',') || s.includes('"') || s.includes('\n')) return '"' + s.replace(/"/g, '""') + '"';
      return s;
    };
    const rows = data.map(e => headers.map(h => escape(e[h])).join(','));
    const csv = [headers.join(','), ...rows].join('\n');
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `errors_${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const btnBase = {
    borderRadius: '9999px', padding: '0.4rem 0.75rem', cursor: 'pointer',
    fontSize: '0.85rem', fontWeight: 600, border: '1px solid var(--color-border, #334155)',
    background: 'transparent', color: 'var(--color-text, #e2e8f0)',
  };
  const btnDanger = { ...btnBase, borderColor: 'var(--color-danger, #ef4444)', color: 'var(--color-danger, #ef4444)' };
  const btnAccent = { ...btnBase, borderColor: 'var(--color-accent, #22c55e)', color: 'var(--color-accent, #22c55e)' };

  return (
    <Panel>
      {/* Toolbar */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '0.75rem', marginBottom: '1rem' }}>
        <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: '0.25rem', cursor: 'pointer', fontSize: '0.85rem' }}>
            <input type="checkbox" checked={selected.size === errors.length && errors.length > 0} onChange={toggleSelectAll} />
            Все
          </label>
          <Select value={filterRange} onChange={(e) => setFilterRange(e.target.value)} className="min-w-[100px]! text-sm! py-2!">
            {DATE_RANGES.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
          </Select>
          <Select value={filterType} onChange={(e) => setFilterType(e.target.value)} className="min-w-[140px]! text-sm! py-2!">
            <option value="">Все типы</option>
            {availableTypes.map((t) => <option key={t} value={t}>{t}</option>)}
          </Select>
          <span style={{ color: 'var(--color-text-muted, #94a3b8)', fontSize: '0.85rem' }}>
            {errors.length} ошибок {selected.size > 0 && `(${selected.size} выбр.)`}
          </span>
        </div>
        <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
          <button onClick={fetchErrors} style={btnBase} title="Обновить">↻</button>
          <button onClick={handleCopyAll} disabled={errors.length === 0} style={{ ...btnAccent, opacity: errors.length === 0 ? 0.4 : 1 }}>
            📋 Копировать всё
          </button>
          {selected.size > 0 && (
            <button onClick={handleCopySelected} style={btnAccent}>
              📋 Копировать выбр.
            </button>
          )}
          <button onClick={downloadJSON} disabled={errors.length === 0} style={{ ...btnBase, opacity: errors.length === 0 ? 0.4 : 1 }}>
            ⬇ JSON
          </button>
          <button onClick={downloadCSV} disabled={errors.length === 0} style={{ ...btnBase, opacity: errors.length === 0 ? 0.4 : 1 }}>
            ⬇ CSV
          </button>
          {selected.size > 0 && (
            <button onClick={handleDeleteSelected} disabled={deleting} style={{ ...btnDanger, opacity: deleting ? 0.5 : 1 }}>
              🗑 Удалить выбр.
            </button>
          )}
          <button onClick={handleDeleteAll} disabled={deleting || errors.length === 0} style={{ ...btnDanger, opacity: deleting || errors.length === 0 ? 0.4 : 1 }}>
            🗑 Удалить все
          </button>
        </div>
      </div>

      <div style={{ fontSize: '0.75rem', color: 'var(--color-text-muted, #94a3b8)', marginBottom: '0.5rem' }}>
        Автообновление каждые 30 сек
      </div>

      {fetchError && (
        <div style={{
          background: 'rgba(201,61,61,0.12)', color: 'var(--color-danger, #ef4444)',
          borderRadius: '12px', padding: '0.75rem 1rem', marginBottom: '1rem', fontSize: '0.9rem',
        }}>
          {fetchError}
        </div>
      )}

      {loading ? (
        <div style={{ textAlign: 'center', padding: '2rem', color: 'var(--color-text-muted, #94a3b8)' }}>Загрузка…</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: '0' }}>
          {errors.length === 0 && (
            <div style={{ textAlign: 'center', padding: '2rem', color: 'var(--color-text-muted, #94a3b8)' }}>
              Нет ошибок за выбранный период
            </div>
          )}

          {errors.map((err) => {
            const isExpanded = expandedId === err.id;
            const isSelected = selected.has(err.id);
            return (
              <div
                key={err.id}
                style={{ borderBottom: '1px solid var(--color-border, #334155)' }}
              >
                <div
                  style={{
                    display: 'grid',
                    gridTemplateColumns: '2rem 1.4fr 1fr 2.5fr 1.5fr',
                    gap: '0.5rem',
                    alignItems: 'center',
                    padding: '0.55rem 0.75rem',
                    fontSize: '0.88rem',
                    cursor: 'pointer',
                    background: isSelected ? 'rgba(34,197,94,0.08)' : 'transparent',
                  }}
                  onClick={() => setExpandedId(isExpanded ? null : err.id)}
                >
                  <input
                    type="checkbox"
                    checked={isSelected}
                    onClick={(e) => e.stopPropagation()}
                    onChange={() => toggleSelect(err.id)}
                  />
                  <span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted, #94a3b8)', whiteSpace: 'nowrap' }}>
                    {fmtDate(err.created_at)}
                  </span>
                  <Badge tone={ERROR_TONES[err.error_type] || 'neutral'}>
                    {err.error_type || 'Unknown'}
                  </Badge>
                  <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={err.message}>
                    {trunc(err.message, 120)}
                  </span>
                  <span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted, #94a3b8)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={err.url}>
                    {trunc(err.url, 40)}
                  </span>
                </div>

                {isExpanded && (
                  <div style={{
                    padding: '0.75rem 1rem 1rem',
                    background: 'var(--color-surface-strong, #1e293b)',
                    fontSize: '0.85rem',
                    display: 'flex',
                    flexDirection: 'column',
                    gap: '0.75rem',
                  }}>
                    <div>
                      <strong>Сообщение:</strong>
                      <pre style={{
                        margin: '0.25rem 0 0', whiteSpace: 'pre-wrap', wordBreak: 'break-word',
                        fontFamily: 'monospace', fontSize: '0.82rem',
                      }}>
                        {err.message || '—'}
                      </pre>
                    </div>
                    <div>
                      <strong>Стек:</strong>
                      <pre style={{
                        margin: '0.25rem 0 0', whiteSpace: 'pre-wrap', wordBreak: 'break-word',
                        fontFamily: 'monospace', fontSize: '0.82rem',
                        background: 'var(--color-surface, #0f172a)', padding: '0.5rem',
                        borderRadius: '8px', border: '1px solid var(--color-border, #334155)',
                        maxHeight: '250px', overflow: 'auto',
                      }}>
                        {err.stack || '—'}
                      </pre>
                    </div>
                    <div>
                      <strong>Props:</strong>
                      <pre style={{
                        margin: '0.25rem 0 0', whiteSpace: 'pre-wrap', wordBreak: 'break-word',
                        fontFamily: 'monospace', fontSize: '0.82rem',
                        background: 'var(--color-surface, #0f172a)', padding: '0.5rem',
                        borderRadius: '8px', border: '1px solid var(--color-border, #334155)',
                        maxHeight: '180px', overflow: 'auto',
                      }}>
                        {err.props || '—'}
                      </pre>
                    </div>
                    <div style={{
                      display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.5rem',
                      fontSize: '0.82rem', color: 'var(--color-text-muted, #94a3b8)',
                    }}>
                      <div><strong>URL:</strong> {err.url || '—'}</div>
                      <div><strong>Компонент:</strong> {err.component || '—'}</div>
                      <div><strong>Строка:</strong> {err.line_number ?? '—'}:{err.column_number ?? '—'}</div>
                      <div><strong>UA:</strong> {trunc(err.user_agent, 60)}</div>
                      {err.user_id && <div style={{ gridColumn: '1 / -1' }}><strong>User ID:</strong> {err.user_id}</div>}
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
                      <button onClick={() => handleDeleteOne(err.id)} disabled={deleting} style={{ ...btnDanger, fontSize: '0.8rem' }}>
                        Удалить запись
                      </button>
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {copied && (
        <div style={{
          position: 'fixed', bottom: '1rem', right: '1rem',
          background: 'var(--color-accent, #22c55e)', color: '#fff',
          padding: '0.5rem 1rem', borderRadius: '9999px', fontSize: '0.85rem',
          fontWeight: 600, zIndex: 1000,
        }}>
          Скопировано!
        </div>
      )}
    </Panel>
  );
}
