import { useState } from 'react'
import Card from '../components/Card'
import Button from '../components/Button'
import Field from '../components/Field'
import SequenceInput from '../components/SequenceInput'
import TaxIdInput from '../components/TaxIdInput'
import {
  CLASSIFIER_OPTIONS,
  DEFAULT_TRAINING_CONFIG,
  FEATURE_SET_OPTIONS,
  SPLIT_OPTIONS,
  SAMPLE_PEPTIDES,
  type TrainingConfig,
  type TrainingResult,
} from '../data/mockData'
import { trainDetectability } from '../lib/api'

export default function DetectabilityTraining() {
  const [input, setInput] = useState('')
  const [taxId, setTaxId] = useState('')
  const [useDefaults, setUseDefaults] = useState(true)
  const [cfg, setCfg] = useState<TrainingConfig>(DEFAULT_TRAINING_CONFIG)
  const [training, setTraining] = useState(false)
  const [result, setResult] = useState<TrainingResult | null>(null)
  const [live, setLive] = useState(false)
  const [downloadUrl, setDownloadUrl] = useState<string | null>(null)
  const [dataUrl, setDataUrl] = useState<string | null>(null)
  const [errorMsg, setErrorMsg] = useState<string | null>(null)

  const canRun = input.trim().length > 0 && taxId.length > 0 && !training

  function set<K extends keyof TrainingConfig>(k: K, v: TrainingConfig[K]) {
    setUseDefaults(false)
    setCfg((c) => ({ ...c, [k]: v }))
  }

  // Pfly is a coupled choice: picking it in either the classifier or the feature-set
  // dropdown keeps the other in sync (and de-selecting it restores the default).
  function setClassifier(v: string) {
    setUseDefaults(false)
    setCfg((c) => ({
      ...c,
      classifier: v,
      featureSet:
        v === 'pfly'
          ? 'pfly'
          : c.featureSet === 'pfly'
            ? DEFAULT_TRAINING_CONFIG.featureSet
            : c.featureSet,
    }))
  }
  function setFeatureSet(v: string) {
    setUseDefaults(false)
    setCfg((c) => ({
      ...c,
      featureSet: v,
      classifier:
        v === 'pfly'
          ? 'pfly'
          : c.classifier === 'pfly'
            ? DEFAULT_TRAINING_CONFIG.classifier
            : c.classifier,
    }))
  }

  function toggleDefaults(on: boolean) {
    setUseDefaults(on)
    if (on) setCfg(DEFAULT_TRAINING_CONFIG)
  }

  async function train() {
    setTraining(true)
    setResult(null)
    setErrorMsg(null)
    setDownloadUrl(null)
    setDataUrl(null)
    try {
      const out = await trainDetectability(input, taxId, cfg)
      setResult(out.result)
      setLive(out.live)
      setDownloadUrl(out.downloadUrl)
      setDataUrl(out.dataUrl)
      setErrorMsg(out.error ?? null)
    } finally {
      setTraining(false)
    }
  }

  return (
    <main className="page">
      <div className="page-header">
        <h1>Train a Detectability Model</h1>
        <p className="lead">
          Give detected peptides and a species tax ID, pick your specs or use the
          defaults, and train a model. Then download the model and processed data.
        </p>
      </div>

      <div className="grid-2">
        <Card title="Training data">
          <SequenceInput
            label="Detected peptide sequences (positives)"
            value={input}
            onChange={setInput}
            onLoadExample={() => setInput(SAMPLE_PEPTIDES)}
          />
          <TaxIdInput value={taxId} onChange={setTaxId} />
        </Card>

        <Card
          title="Model specifications"
          actions={
            <label
              className="option"
              style={{ padding: '6px 10px', marginBottom: 0 }}
            >
              <input
                type="checkbox"
                checked={useDefaults}
                onChange={(e) => toggleDefaults(e.target.checked)}
              />
              <span className="option-title" style={{ fontSize: 'var(--text-sm)' }}>
                Use defaults
              </span>
            </label>
          }
        >
          <Field label="Classifier">
            <select
              value={cfg.classifier}
              onChange={(e) => setClassifier(e.target.value)}
            >
              {CLASSIFIER_OPTIONS.map((o) => (
                <option key={o.id} value={o.id}>
                  {o.label} · {o.desc}
                </option>
              ))}
            </select>
          </Field>
          <Field
            label="Feature set"
            hint={
              cfg.featureSet === 'pfly'
                ? 'Pfly reads the sequence directly, no separate classifier'
                : undefined
            }
          >
            <select
              value={cfg.featureSet}
              onChange={(e) => setFeatureSet(e.target.value)}
            >
              {FEATURE_SET_OPTIONS.map((o) => (
                <option key={o.id} value={o.id}>
                  {o.label} · {o.desc}
                </option>
              ))}
            </select>
          </Field>
          <Field label="Split (cross-validation grouping)">
            <select
              value={cfg.split}
              onChange={(e) => set('split', e.target.value)}
            >
              {SPLIT_OPTIONS.map((o) => (
                <option key={o.id} value={o.id}>
                  {o.label} · {o.desc}
                </option>
              ))}
            </select>
          </Field>
          <div className="grid-2" style={{ gap: 14 }}>
            <Field label="CV folds">
              <input
                type="number"
                min={2}
                max={10}
                value={cfg.folds}
                onChange={(e) => set('folds', Number(e.target.value))}
              />
            </Field>
            <Field label="Negative balance">
              <select
                value={cfg.balance}
                onChange={(e) => set('balance', e.target.value)}
              >
                {['1:1', '1:3', '1:5'].map((b) => (
                  <option key={b} value={b}>
                    {b}
                  </option>
                ))}
              </select>
            </Field>
          </div>

          <div style={{ marginTop: 8 }}>
            <Button onClick={train} disabled={!canRun}>
              {training ? 'Training…' : 'Train model'}
            </Button>
            {!canRun && !training && (
              <p
                className="muted"
                style={{ fontSize: 'var(--text-sm)', marginTop: 8, marginBottom: 0 }}
              >
                Add positive peptides and a species tax ID to train.
              </p>
            )}
          </div>
        </Card>
      </div>

      <Card title="Training result">
        {training ? (
          <div className="empty-state">
            Training model… computing features, sampling k-mer negatives, and
            running cross-validation.
          </div>
        ) : result == null ? (
          <div className="empty-state">
            Train a model to see cross-validation metrics and per-fold results.
          </div>
        ) : (
          <>
            <p style={{ marginTop: 0, marginBottom: 12 }}>
              <span className={'badge ' + (live ? 'badge-good' : 'badge-muted')}>
                {live ? 'Live training' : 'Offline preview'}
              </span>{' '}
              <span className="muted" style={{ fontSize: 'var(--text-sm)' }}>
                {live
                  ? 'Trained on the server: assign proteins, sample negatives, protein-grouped CV.'
                  : 'Illustrative numbers; the training backend is not reachable.'}
              </span>
            </p>
            {errorMsg && (
              <p className="error-banner" style={{ marginTop: 0, marginBottom: 12 }}>
                Backend could not train on this input: {errorMsg}
              </p>
            )}
            <div className="stat-row">
              <div className="stat">
                <div className="stat-value">{result.rocAuc.toFixed(3)}</div>
                <div className="stat-label">
                  Mean ROC-AUC ({cfg.folds}-fold CV)
                </div>
              </div>
              <div className="stat">
                <div className="stat-value">{result.prAuc.toFixed(3)}</div>
                <div className="stat-label">Mean PR-AUC</div>
              </div>
              <div className="stat">
                <div className="stat-value">{result.nPositives}</div>
                <div className="stat-label">Positives</div>
              </div>
              <div className="stat">
                <div className="stat-value">{result.nNegatives}</div>
                <div className="stat-label">Negatives (sampled)</div>
              </div>
            </div>

            <div className="table-wrap">
              <table className="table">
                <thead>
                  <tr>
                    <th>Fold</th>
                    <th className="num">ROC-AUC</th>
                    <th className="num">PR-AUC</th>
                    <th className="num"># train</th>
                    <th className="num"># test</th>
                  </tr>
                </thead>
                <tbody>
                  {result.folds.map((f) => (
                    <tr key={f.fold}>
                      <td>Fold {f.fold}</td>
                      <td className="num">{f.rocAuc.toFixed(3)}</td>
                      <td className="num">{f.prAuc.toFixed(3)}</td>
                      <td className="num">{f.nTrain}</td>
                      <td className="num">{f.nTest}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            <div style={{ marginTop: 16, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              {downloadUrl ? (
                <a href={downloadUrl} download>
                  <Button variant="secondary">Download trained model (.joblib)</Button>
                </a>
              ) : (
                <Button variant="secondary" disabled>
                  Download trained model (train on the backend to enable)
                </Button>
              )}
              {dataUrl && (
                <a href={dataUrl} download>
                  <Button variant="secondary">Download processed data (.csv)</Button>
                </a>
              )}
            </div>
            {dataUrl && (
              <p className="muted" style={{ fontSize: 'var(--text-xs)', marginTop: 8, marginBottom: 0 }}>
                The processed dataset has one row per peptide (your detected peptides + sampled
                negatives) with its assigned protein, bioactivity / cytotoxicity / allergen screening,
                and the full feature matrix (physicochemical + PepBERT + ESM2 embeddings).
              </p>
            )}
          </>
        )}
      </Card>
    </main>
  )
}
