import { Dialog, DialogContent, DialogHeader, DialogTitle, Button } from '@/components/ui';
import { useCallback, useEffect, useState } from 'react';
import { useExchanges } from '../hooks/useExchanges';
import type { CreateProviderMappingRequest } from '../types/index';

interface AddProviderMappingDialogProps {
  isOpen: boolean;
  exchangeId: string;
  exchangeName: string;
  onClose: () => void;
  onCreateMapping: (request: CreateProviderMappingRequest) => Promise<boolean | void>;
}

interface UnmappedExchange {
  provider_exchange_code: string;
  provider_exchange_name: string;
  country_code?: string;
  currency?: string;
  symbol_count?: number;
}

export function AddProviderMappingDialog({
  isOpen,
  exchangeId,
  exchangeName,
  onClose,
  onCreateMapping,
}: AddProviderMappingDialogProps) {
  const { fetchProviders, fetchUnmappedProviderExchanges } = useExchanges();
  const [providers, setProviders] = useState<string[]>([]);
  const [selectedProvider, setSelectedProvider] = useState('');
  const [unmappedExchanges, setUnmappedExchanges] = useState<UnmappedExchange[]>([]);
  const [selectedProviderExchange, setSelectedProviderExchange] = useState('');
  const [loading, setLoading] = useState(false);
  const [providersLoading, setProvidersLoading] = useState(false);
  const [exchangesLoading, setExchangesLoading] = useState(false);

  const loadProviders = useCallback(async () => {
    setProvidersLoading(true);
    try {
      const providersData = await fetchProviders();
      setProviders(providersData);
    } catch {
      // Error loading providers - could add toast notification here
    } finally {
      setProvidersLoading(false);
    }
  }, [fetchProviders]);

  const loadUnmappedExchanges = useCallback(
    async (provider: string) => {
      setExchangesLoading(true);
      try {
        const exchangesData = await fetchUnmappedProviderExchanges(provider);
        setUnmappedExchanges(exchangesData);
      } catch {
        // Error loading unmapped exchanges - could add toast notification here
      } finally {
        setExchangesLoading(false);
      }
    },
    [fetchUnmappedProviderExchanges]
  );

  // Load providers on mount
  useEffect(() => {
    if (isOpen) {
      loadProviders();
    }
  }, [isOpen, loadProviders]);

  // Load unmapped exchanges when provider changes
  useEffect(() => {
    if (selectedProvider) {
      loadUnmappedExchanges(selectedProvider);
    } else {
      setUnmappedExchanges([]);
      setSelectedProviderExchange('');
    }
  }, [selectedProvider, loadUnmappedExchanges]);

  const handleSubmit = useCallback(
    async (e: React.FormEvent) => {
      e.preventDefault();

      if (!selectedProvider || !selectedProviderExchange) {
        return;
      }

      const selectedExchange = unmappedExchanges.find(
        exchange => exchange.provider_exchange_code === selectedProviderExchange
      );

      if (!selectedExchange) {
        return;
      }

      setLoading(true);
      try {
        const request: CreateProviderMappingRequest = {
          provider: selectedProvider,
          provider_exchange_code: selectedExchange.provider_exchange_code,
          provider_exchange_name: selectedExchange.provider_exchange_name,
          master_exchange_id: exchangeId,
          country_code: selectedExchange.country_code,
          currency: selectedExchange.currency,
          confidence: 1.0,
          active: false,
          verified: false,
        };

        await onCreateMapping(request);
      } catch {
        // Error creating provider mapping - could add toast notification here
      } finally {
        setLoading(false);
      }
    },
    [selectedProvider, selectedProviderExchange, unmappedExchanges, exchangeId, onCreateMapping]
  );

  const handleClose = useCallback(() => {
    setSelectedProvider('');
    setSelectedProviderExchange('');
    setUnmappedExchanges([]);
    onClose();
  }, [onClose]);

  return (
    <Dialog open={isOpen} onOpenChange={handleClose}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>Add Provider Mapping</DialogTitle>
          <p className="text-sm text-text-muted">
            Map a provider exchange to <strong>{exchangeName}</strong>
          </p>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4">
          {/* Provider Selection */}
          <div>
            <label htmlFor="provider" className="block text-sm font-medium text-text-primary mb-1">
              Provider
            </label>
            <select
              id="provider"
              value={selectedProvider}
              onChange={e => setSelectedProvider(e.target.value)}
              disabled={providersLoading}
              className="w-full px-3 py-2 border border-border rounded-md bg-surface text-text-primary focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
              required
            >
              <option value="">
                {providersLoading ? 'Loading providers...' : 'Select a provider'}
              </option>
              {providers.map(provider => (
                <option key={provider} value={provider}>
                  {provider.toUpperCase()}
                </option>
              ))}
            </select>
          </div>

          {/* Provider Exchange Selection */}
          <div>
            <label
              htmlFor="providerExchange"
              className="block text-sm font-medium text-text-primary mb-1"
            >
              Provider Exchange
            </label>
            <select
              id="providerExchange"
              value={selectedProviderExchange}
              onChange={e => setSelectedProviderExchange(e.target.value)}
              disabled={!selectedProvider || exchangesLoading}
              className="w-full px-3 py-2 border border-border rounded-md bg-surface text-text-primary focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
              required
            >
              <option value="">
                {!selectedProvider
                  ? 'Select a provider first'
                  : exchangesLoading
                  ? 'Loading exchanges...'
                  : unmappedExchanges.length === 0
                  ? 'No unmapped exchanges available'
                  : 'Select an exchange'}
              </option>
              {unmappedExchanges.map(exchange => (
                <option key={exchange.provider_exchange_code} value={exchange.provider_exchange_code}>
                  {exchange.provider_exchange_code} - {exchange.provider_exchange_name}
                  {exchange.country_code && ` (${exchange.country_code})`}
                </option>
              ))}
            </select>
            {selectedProvider && unmappedExchanges.length === 0 && !exchangesLoading && (
              <p className="text-xs text-text-muted mt-1">
                All exchanges for this provider are already mapped.
              </p>
            )}
          </div>

          {/* Selected Exchange Info */}
          {selectedProviderExchange && (
            <div className="p-3 bg-surface-secondary rounded-md">
              <h4 className="text-sm font-medium text-text-primary mb-2">Selected Exchange Info</h4>
              {(() => {
                const exchange = unmappedExchanges.find(
                  ex => ex.provider_exchange_code === selectedProviderExchange
                );
                if (!exchange) {return null;}

                return (
                  <div className="space-y-1 text-xs">
                    <div>
                      <span className="text-text-muted">Code:</span>{' '}
                      <span className="font-mono">{exchange.provider_exchange_code}</span>
                    </div>
                    <div>
                      <span className="text-text-muted">Name:</span> {exchange.provider_exchange_name}
                    </div>
                    {exchange.country_code && (
                      <div>
                        <span className="text-text-muted">Country:</span> {exchange.country_code}
                      </div>
                    )}
                    {exchange.currency && (
                      <div>
                        <span className="text-text-muted">Currency:</span> {exchange.currency}
                      </div>
                    )}
                    {exchange.symbol_count && (
                      <div>
                        <span className="text-text-muted">Symbols:</span> {exchange.symbol_count}
                      </div>
                    )}
                  </div>
                );
              })()}
            </div>
          )}

          {/* Action Buttons */}
          <div className="flex justify-end gap-2 pt-4">
            <Button type="button" variant="outline" onClick={handleClose} disabled={loading}>
              Cancel
            </Button>
            <Button
              type="submit"
              disabled={!selectedProvider || !selectedProviderExchange || loading}
            >
              {loading ? 'Creating...' : 'Create Mapping'}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}