import { useState, useCallback, useReducer } from 'react';
import { ImageDrop } from './components/ImageDrop.jsx';
import { JobCard } from './components/JobCard.jsx';
import { useJobSocket } from './hooks/useJobSocket.js';
import { submitJob } from './lib/api.js';
import { MODELS, DEFAULT_MODEL_ID } from './models.js';

// Group models for the dropdown optgroup
const GATEWAY_MODELS = MODELS.filter(m => m.provider !== 'ollama');
const OLLAMA_MODELS  = MODELS.filter(m => m.provider === 'ollama');

// ---------------------------------------------------------------------------
// Jobs state reducer
// ---------------------------------------------------------------------------
function jobsReducer(state, action) {
  switch (action.type) {
    case 'init':   return action.jobs;
    case 'upsert': {
      const idx = state.findIndex(j => j.id === action.job.id);
      if (idx === -1) return [action.job, ...state];
      const next = [...state];
      next[idx] = action.job;
      return next;
    }
    default: return state;
  }
}

// ---------------------------------------------------------------------------
// App
// ---------------------------------------------------------------------------
export default function App() {
  const [jobs, dispatch]    = useReducer(jobsReducer, []);
  const [prompt, setPrompt] = useState('');
  const [imageFile, setImageFile] = useState(null);
  const [modelId, setModelId]     = useState(DEFAULT_MODEL_ID);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError]   = useState('');
  const [pending, setPending] = useState(0);

  useJobSocket(useCallback(msg => {
    if (msg.type === 'init')       dispatch({ type: 'init',   jobs: msg.jobs });
    if (msg.type === 'job_update') dispatch({ type: 'upsert', job:  msg.job  });
    if (msg.type === 'queue_stats') setPending(msg.pending);
  }, []));

  async function handleSubmit(e) {
    e.preventDefault();
    if (!prompt.trim()) return setError('Please enter a prompt.');
    if (!imageFile)     return setError('Please select or drop an image.');
    setError('');
    setSubmitting(true);
    try {
      await submitJob(prompt, imageFile, modelId);
      setPrompt('');
      setImageFile(null);
    } catch (err) {
      setError(err.message);
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="app">
      <header className="app-header">
        <div className="header-inner">
          <h1 className="app-title">
            <span className="title-eye">◉</span> Vision Jobs
          </h1>
        </div>
      </header>

      <main className="app-main">
        <section className="submit-section">
          <form className="submit-form" onSubmit={handleSubmit} noValidate>
            <ImageDrop file={imageFile} onFile={setImageFile} />

            {/* Model selector */}
            <div className="model-row">
              <label className="model-label" htmlFor="model-select">Model</label>
              <select
                id="model-select"
                className="model-select"
                value={modelId}
                onChange={e => setModelId(e.target.value)}
                disabled={submitting}
              >
                <optgroup label="Cloud Providers">
                  {GATEWAY_MODELS.map(m => (
                    <option key={m.id} value={m.id}>{m.label}</option>
                  ))}
                </optgroup>
                <optgroup label="Ollama Cloud">
                  {OLLAMA_MODELS.map(m => (
                    <option key={m.id} value={m.id}>{m.label}</option>
                  ))}
                </optgroup>
              </select>
            </div>

            <div className="prompt-row">
              <textarea
                className="prompt-input"
                placeholder="Describe what you want to know about this image…"
                value={prompt}
                onChange={e => setPrompt(e.target.value)}
                rows={3}
                disabled={submitting}
              />
              <button
                type="submit"
                className="submit-btn"
                disabled={submitting || !prompt.trim() || !imageFile}
              >
                {submitting ? <span className="spinner" /> : (
                  <>
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
                      stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
                      <path d="M5 12h14M12 5l7 7-7 7"/>
                    </svg>
                    Analyze
                  </>
                )}
              </button>
            </div>

            {error && <p className="form-error" role="alert">{error}</p>}
          </form>
        </section>

        <section className="jobs-section">
          <div className="jobs-header">
            <h2 className="jobs-title">Jobs</h2>
            {pending > 0 && (
              <span className="queue-badge">{pending} queued</span>
            )}
          </div>

          {jobs.length === 0 ? (
            <div className="jobs-empty">
              <span>No jobs yet — submit an image above.</span>
            </div>
          ) : (
            <div className="jobs-list">
              {jobs.map(job => <JobCard key={job.id} job={job} />)}
            </div>
          )}
        </section>
      </main>
    </div>
  );
}
