import { useEffect, useRef, useState } from 'react';
import { fetchScrapeJob, fetchScrapeJobs, postScrape } from '../api';
import type { ScrapeJob, ScrapeJobDetail } from '../types';
import './Scraper.css';

function PriceCard({ result }: { result: NonNullable<ScrapeJobDetail['results']>[number] }) {
  const entries = Object.entries(result.prices);
  return (
    <div className="price-card">
      <div className="price-card-title">{result.model_name}</div>
      <div className="price-card-url">{result.url}</div>
      <div className="price-entries">
        {entries.length === 0 ? (
          <span className="no-price">No price data</span>
        ) : (
          entries.map(([key, val]) => (
            <div key={key} className="price-entry">
              <span className="price-key">{key}</span>
              <span className="price-val">{JSON.stringify(val)}</span>
            </div>
          ))
        )}
      </div>
      <div className="price-time">Scraped: {new Date(result.scraped_at).toLocaleString()}</div>
    </div>
  );
}

export function Scraper() {
  const [urlInput, setUrlInput] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [activeJob, setActiveJob] = useState<ScrapeJobDetail | null>(null);
  const [history, setHistory] = useState<ScrapeJob[]>([]);
  const [error, setError] = useState<string | null>(null);
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const loadHistory = () => {
    fetchScrapeJobs().then(setHistory).catch(() => {});
  };

  useEffect(() => {
    loadHistory();
  }, []);

  const stopPolling = () => {
    if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; }
  };

  const startPolling = (jobId: string) => {
    stopPolling();
    pollRef.current = setInterval(async () => {
      try {
        const detail = await fetchScrapeJob(jobId);
        setActiveJob(detail);
        if (detail.status === 'done' || detail.status === 'failed') {
          stopPolling();
          loadHistory();
        }
      } catch {
        stopPolling();
      }
    }, 2000);
  };

  useEffect(() => () => stopPolling(), []);

  const handleSubmit = async () => {
    const urls = urlInput.split('\n').map((u) => u.trim()).filter(Boolean);
    if (urls.length === 0) return;
    setSubmitting(true);
    setError(null);
    setActiveJob(null);
    try {
      const job = await postScrape(urls);
      setActiveJob({ ...job, results: undefined });
      startPolling(job.job_id);
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setSubmitting(false);
    }
  };

  const handleHistoryClick = async (jobId: string) => {
    try {
      const detail = await fetchScrapeJob(jobId);
      setActiveJob(detail);
      stopPolling();
      if (detail.status === 'pending' || detail.status === 'running') {
        startPolling(jobId);
      }
    } catch {
      setError('Failed to load job details');
    }
  };

  return (
    <div className="scraper-page">
      <header className="scraper-header">
        <span className="scraper-title">PRICE_SCRAPER</span>
      </header>

      <div className="scraper-input-area">
        <textarea
          className="url-input"
          placeholder="Enter URLs (one per line)&#10;https://bailian.console.aliyun.com/..."
          value={urlInput}
          onChange={(e) => setUrlInput(e.target.value)}
          rows={4}
        />
        <button className="submit-btn" onClick={handleSubmit} disabled={submitting}>
          {submitting ? 'SUBMITTING…' : '▶ SCRAPE'}
        </button>
      </div>

      {error && <div className="error-banner">ERROR: {error}</div>}

      {activeJob && (
        <div className={`job-status job-status--${activeJob.status}`}>
          <span>JOB {activeJob.job_id.slice(0, 8)}…</span>
          <span className="job-badge">{activeJob.status.toUpperCase()}</span>
        </div>
      )}

      {activeJob?.status === 'failed' && (
        <div className="error-card">
          <div className="error-card-title">SCRAPE FAILED</div>
          <pre className="error-detail">{activeJob.error}</pre>
        </div>
      )}

      {activeJob?.status === 'done' && activeJob.results && (
        <div className="results-section">
          {activeJob.results.map((r) => (
            <PriceCard key={r.url} result={r} />
          ))}
        </div>
      )}

      {history.length > 0 && (
        <section className="history-section">
          <div className="section-title">HISTORY</div>
          <ul className="history-list">
            {history.map((job) => (
              <li
                key={job.job_id}
                className={`history-item history-item--${job.status}`}
                onClick={() => handleHistoryClick(job.job_id)}
              >
                <span className="history-id">{job.job_id.slice(0, 8)}…</span>
                <span className="history-status">{job.status}</span>
                <span className="history-time">{new Date(job.created_at).toLocaleString()}</span>
              </li>
            ))}
          </ul>
        </section>
      )}
    </div>
  );
}
