import { useQuery, UseQueryOptions } from '@tanstack/react-query';
import { gql } from 'graphql-request';
import { fetchGraphQL, createQueryKey } from '../client';

// Types
export interface LinkedAccount {
  id: string;
  accountNumber: string;
  name: string;
}

export interface BankAccountInfo {
  accountId: string;
  iban: string;
  currency: string;
  name: string | null;
  linkedAccountId: string | null;
  linkedAccount: LinkedAccount | null;
  importFromDate: string | null;
}

export interface BankConnection {
  id: string;
  companyId: string;
  aspspName: string;
  status: 'initiated' | 'established' | 'failed' | 'disconnected';
  validUntil: string | null;
  failureReason: string | null;
  createdAt: string;
  updatedAt: string;
  isActive: boolean;
  accounts: BankAccountInfo[] | null;
}

export interface Aspsp {
  name: string;
  country: string;
  logo: string;
  psuTypes: string[];
  personalAccounts: boolean;
  businessAccounts: boolean;
}

// GraphQL Queries
const AVAILABLE_BANKS_QUERY = gql`
  query AvailableBanks($country: String) {
    availableBanks(country: $country) {
      name
      country
      logo
      psuTypes
      personalAccounts
      businessAccounts
    }
  }
`;

const BANK_CONNECTIONS_QUERY = gql`
  query BankConnections($companyId: ID!) {
    bankConnections(companyId: $companyId) {
      id
      companyId
      aspspName
      status
      validUntil
      failureReason
      createdAt
      updatedAt
      isActive
      accounts {
        accountId
        iban
        currency
        name
        linkedAccountId
        linkedAccount {
          id
          accountNumber
          name
        }
        importFromDate
      }
    }
  }
`;

const ACTIVE_BANK_CONNECTIONS_QUERY = gql`
  query ActiveBankConnections($companyId: ID!) {
    activeBankConnections(companyId: $companyId) {
      id
      companyId
      aspspName
      status
      validUntil
      createdAt
      updatedAt
      isActive
      accounts {
        accountId
        iban
        currency
        name
        linkedAccountId
        linkedAccount {
          id
          accountNumber
          name
        }
        importFromDate
      }
    }
  }
`;

// Response types
interface AvailableBanksResponse {
  availableBanks: Aspsp[];
}

interface BankConnectionsResponse {
  bankConnections: BankConnection[];
}

interface ActiveBankConnectionsResponse {
  activeBankConnections: BankConnection[];
}

/**
 * Hook to fetch available banks for connection
 */
export function useAvailableBanks(
  country: string = 'DK',
  options?: Omit<UseQueryOptions<Aspsp[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('availableBanks', { country }),
    queryFn: async () => {
      const data = await fetchGraphQL<AvailableBanksResponse>(AVAILABLE_BANKS_QUERY, { country });
      return data.availableBanks;
    },
    staleTime: 1000 * 60 * 60, // Banks don't change often, cache for 1 hour
    ...options,
  });
}

/**
 * Hook to fetch all bank connections for a company
 */
export function useBankConnections(
  companyId: string | undefined,
  options?: Omit<UseQueryOptions<BankConnection[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('bankConnections', { companyId }),
    queryFn: async () => {
      if (!companyId) return [];
      const data = await fetchGraphQL<BankConnectionsResponse>(BANK_CONNECTIONS_QUERY, { companyId });
      return data.bankConnections;
    },
    enabled: !!companyId,
    ...options,
  });
}

/**
 * Hook to fetch only active bank connections for a company
 */
export function useActiveBankConnections(
  companyId: string | undefined,
  options?: Omit<UseQueryOptions<BankConnection[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('activeBankConnections', { companyId }),
    queryFn: async () => {
      if (!companyId) return [];
      const data = await fetchGraphQL<ActiveBankConnectionsResponse>(ACTIVE_BANK_CONNECTIONS_QUERY, { companyId });
      return data.activeBankConnections;
    },
    enabled: !!companyId,
    ...options,
  });
}
