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 {
  useCreateSubscription,
  useExchanges,
  useExchangeInstruments,
} from '../api/hooks';
import AppBreadcrumb from '../components/AppBreadcrumb';

export default function AddSubscriptionPage() {
  const navigate = useNavigate();
  const [exchange, setExchange] = useState('');
  const [pair, setPair] = useState('');
  const [selectedKinds, setSelectedKinds] = useState<string[]>(['PublicTrades']);

  const exchanges = useExchanges();
  const createMutation = useCreateSubscription();

  const selectedExchange = useMemo(
    () => exchanges.data?.find((ex) => ex.name === exchange) ?? null,
    [exchange, exchanges.data],
  );

  const supportsLookup = selectedExchange?.supports_instrument_lookup ?? false;
  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]);

  const availableKinds = selectedExchange?.supported_sub_kinds ?? [];

  function handleExchangeChange(name: string) {
    setExchange(name);
    setPair('');
    setSelectedKinds(['PublicTrades']);
  }

  function toggleKind(kind: string) {
    setSelectedKinds((prev) =>
      prev.includes(kind) ? prev.filter((k) => k !== kind) : [...prev, kind],
    );
  }

  function handleSubmit(e: FormEvent) {
    e.preventDefault();
    if (!exchange || !pair || selectedKinds.length === 0) return;
    createMutation.mutate(
      { exchange, pair, sub_kinds: selectedKinds },
      { onSuccess: () => navigate('/subscriptions') },
    );
  }

  return (
    <Container>
      <AppBreadcrumb />
      <Row>
        <Col lg={6}>
          <Card>
            <Card.Header>Add Subscription</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>
                    {exchanges.data?.map((ex) => (
                      <option key={ex.name} value={ex.name}>{ex.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="instrument-pairs"
                      />
                      <datalist id="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-USDT"
                    />
                  )}
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>Subscription Types</Form.Label>
                  {availableKinds.length === 0 ? (
                    <Form.Text className="text-muted d-block">
                      Select an exchange to see available types
                    </Form.Text>
                  ) : (
                    availableKinds.map((kind) => (
                      <Form.Check
                        key={kind}
                        type="checkbox"
                        label={kind}
                        checked={selectedKinds.includes(kind)}
                        onChange={() => toggleKind(kind)}
                      />
                    ))
                  )}
                </Form.Group>

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

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