import { useState, useMemo, type FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Alert,
  Button,
  Card,
  Col,
  Container,
  Form,
  Row,
  Spinner,
} from 'react-bootstrap';
import { useCreateIngestConfig, useExchangeInstruments } from '../api/hooks';
import AppBreadcrumb from '../components/AppBreadcrumb';

const SUPPORTED_INGEST_EXCHANGES = ['binance_spot', 'binance_futures_usd'];

/** Map exchange name to the source_type expected by the API. */
function exchangeToSourceType(exchange: string): string {
  if (exchange === 'binance_futures_usd') return 'futures_um';
  if (exchange === 'binance_futures_cm') return 'futures_cm';
  return 'spot';
}

const CANDLE_INTERVAL_OPTIONS = ['1m', '5m', '15m', '1h', '4h', '1d'];

export default function AddIngestionPage() {
  const navigate = useNavigate();
  const [exchange, setExchange] = useState('');
  const [pair, setPair] = useState('');
  const [retentionDays, setRetentionDays] = useState(365);
  const [candleRetentionUnlimited, setCandleRetentionUnlimited] = useState(true);
  const [candleRetentionDays, setCandleRetentionDays] = useState(365);
  const [candleIntervals, setCandleIntervals] = useState<string[]>([]);

  const createMutation = useCreateIngestConfig();

  const supportsLookup = exchange === 'binance_spot' || exchange === 'binance_futures_usd';
  const instruments = useExchangeInstruments(supportsLookup ? exchange : null);

  const sortedInstruments = useMemo(() => {
    if (!instruments.data) return [];
    return [...instruments.data].sort((a, b) =>
      `${a.base}-${a.quote}`.localeCompare(`${b.base}-${b.quote}`),
    );
  }, [instruments.data]);

  function handleExchangeChange(name: string) {
    setExchange(name);
    setPair('');
  }

  function toggleInterval(interval: string) {
    setCandleIntervals((prev) =>
      prev.includes(interval) ? prev.filter((i) => i !== interval) : [...prev, interval],
    );
  }

  function handleSubmit(e: FormEvent) {
    e.preventDefault();
    if (!exchange || !pair) return;
    createMutation.mutate(
      {
        exchange,
        pair,
        source_type: exchangeToSourceType(exchange),
        retention_days: retentionDays,
        candle_retention_days: candleRetentionUnlimited ? null : candleRetentionDays,
        candle_intervals: candleIntervals,
      },
      { onSuccess: () => navigate('/ingestion') },
    );
  }

  return (
    <Container>
      <AppBreadcrumb />
      <Row>
        <Col lg={6}>
          <Card>
            <Card.Header>Add Ingestion Config</Card.Header>
            <Card.Body>
              <Form onSubmit={handleSubmit}>
                <Form.Group className="mb-3">
                  <Form.Label>Exchange</Form.Label>
                  <Form.Select
                    value={exchange}
                    onChange={(e) => handleExchangeChange(e.target.value)}
                  >
                    <option value="">Select an exchange...</option>
                    {SUPPORTED_INGEST_EXCHANGES.map((name) => (
                      <option key={name} value={name}>{name}</option>
                    ))}
                  </Form.Select>
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>
                    Pair (BASE-QUOTE)
                    {supportsLookup && instruments.isLoading && (
                      <Spinner size="sm" animation="border" className="ms-2" />
                    )}
                  </Form.Label>
                  {supportsLookup ? (
                    <>
                      <Form.Control
                        value={pair}
                        onChange={(e) => setPair(e.target.value)}
                        placeholder="Type to search instruments..."
                        list="ingest-instrument-pairs"
                      />
                      <datalist id="ingest-instrument-pairs">
                        {sortedInstruments.map((inst) => {
                          const value = `${inst.base}-${inst.quote}`;
                          return <option key={value} value={value} />;
                        })}
                      </datalist>
                    </>
                  ) : (
                    <Form.Control
                      value={pair}
                      onChange={(e) => setPair(e.target.value)}
                      placeholder="e.g. BTC-USDC"
                    />
                  )}
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>Trade Retention (days)</Form.Label>
                  <Form.Control
                    type="number"
                    min={1}
                    value={retentionDays}
                    onChange={(e) => setRetentionDays(parseInt(e.target.value) || 365)}
                  />
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>Candle Retention</Form.Label>
                  <Form.Check
                    type="switch"
                    id="candle-retention-unlimited"
                    label="Unlimited — keep all available history"
                    checked={candleRetentionUnlimited}
                    onChange={(e) => {
                      setCandleRetentionUnlimited(e.target.checked);
                    }}
                    className="mb-2"
                  />
                  {!candleRetentionUnlimited && (
                    <Form.Control
                      type="number"
                      min={1}
                      value={candleRetentionDays}
                      onChange={(e) => setCandleRetentionDays(parseInt(e.target.value) || 365)}
                    />
                  )}
                  <Form.Text className="text-muted">
                    Unlimited fetches all available history from Binance S3 (back to the
                    instrument's listing date). Candles consume far less disk space than trades.
                  </Form.Text>
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>Candle Intervals to sync</Form.Label>
                  <div className="d-flex flex-wrap gap-2">
                    {CANDLE_INTERVAL_OPTIONS.map((interval) => (
                      <Form.Check
                        key={interval}
                        type="checkbox"
                        id={`candle-${interval}`}
                        label={interval}
                        checked={candleIntervals.includes(interval)}
                        onChange={() => toggleInterval(interval)}
                      />
                    ))}
                  </div>
                  <Form.Text className="text-muted">
                    Selected intervals are synced from data.binance.vision alongside trades.
                    Use 1m for highest-resolution candle backtests.
                  </Form.Text>
                </Form.Group>

                <div className="d-flex gap-2">
                  <Button
                    type="submit"
                    disabled={createMutation.isPending || !exchange || !pair}
                  >
                    {createMutation.isPending ? <Spinner size="sm" animation="border" /> : 'Create'}
                  </Button>
                  <Button variant="outline-secondary" onClick={() => navigate('/ingestion')}>
                    Cancel
                  </Button>
                </div>

                {createMutation.isError && (
                  <Alert variant="danger" className="mt-3">
                    {(createMutation.error as Error).message}
                  </Alert>
                )}
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}
