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

// GraphQL Queries
const ORDERS_QUERY = gql`
  query Orders($companyId: ID!, $status: String) {
    orders(companyId: $companyId, status: $status) {
      id
      companyId
      fiscalYearId
      customerId
      customerName
      customerNumber
      orderNumber
      orderDate
      expectedDeliveryDate
      status
      amountExVat
      amountVat
      amountTotal
      uninvoicedAmount
      uninvoicedLineCount
      currency
      notes
      reference
      confirmedAt
      confirmedBy
      cancelledAt
      cancelledReason
      cancelledBy
      createdBy
      updatedBy
      createdAt
      updatedAt
      lines {
        lineNumber
        productId
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        accountId
        amountExVat
        amountVat
        amountTotal
        isInvoiced
        invoiceId
        invoicedAt
      }
    }
  }
`;

const ORDER_QUERY = gql`
  query Order($id: ID!) {
    order(id: $id) {
      id
      companyId
      fiscalYearId
      customerId
      customerName
      customerNumber
      orderNumber
      orderDate
      expectedDeliveryDate
      status
      amountExVat
      amountVat
      amountTotal
      uninvoicedAmount
      uninvoicedLineCount
      currency
      notes
      reference
      confirmedAt
      confirmedBy
      cancelledAt
      cancelledReason
      cancelledBy
      createdBy
      updatedBy
      createdAt
      updatedAt
      lines {
        lineNumber
        productId
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        accountId
        amountExVat
        amountVat
        amountTotal
        isInvoiced
        invoiceId
        invoicedAt
      }
      uninvoicedLines {
        lineNumber
        productId
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        accountId
        amountExVat
        amountVat
        amountTotal
        isInvoiced
      }
    }
  }
`;

const ORDER_BY_NUMBER_QUERY = gql`
  query OrderByNumber($companyId: ID!, $orderNumber: String!) {
    orderByNumber(companyId: $companyId, orderNumber: $orderNumber) {
      id
      companyId
      fiscalYearId
      customerId
      customerName
      customerNumber
      orderNumber
      orderDate
      expectedDeliveryDate
      status
      amountExVat
      amountVat
      amountTotal
      uninvoicedAmount
      uninvoicedLineCount
      currency
      notes
      reference
      confirmedAt
      confirmedBy
      cancelledAt
      cancelledReason
      cancelledBy
      createdBy
      updatedBy
      createdAt
      updatedAt
      lines {
        lineNumber
        productId
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        accountId
        amountExVat
        amountVat
        amountTotal
        isInvoiced
        invoiceId
        invoicedAt
      }
    }
  }
`;

const ORDERS_BY_CUSTOMER_QUERY = gql`
  query OrdersByCustomer($customerId: ID!, $status: String) {
    ordersByCustomer(customerId: $customerId, status: $status) {
      id
      companyId
      orderNumber
      orderDate
      expectedDeliveryDate
      status
      amountTotal
      uninvoicedAmount
      customerName
    }
  }
`;

const CONFIRMED_ORDERS_QUERY = gql`
  query ConfirmedOrders($companyId: ID!) {
    confirmedOrders(companyId: $companyId) {
      id
      companyId
      customerId
      customerName
      customerNumber
      orderNumber
      orderDate
      expectedDeliveryDate
      status
      amountExVat
      amountVat
      amountTotal
      uninvoicedAmount
      uninvoicedLineCount
      currency
      reference
      lines {
        lineNumber
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        amountExVat
        amountVat
        amountTotal
        isInvoiced
        invoiceId
        invoicedAt
      }
      uninvoicedLines {
        lineNumber
        description
        quantity
        unit
        unitPrice
        discountPercent
        vatCode
        amountExVat
        amountVat
        amountTotal
      }
    }
  }
`;

// Response types
interface OrdersResponse {
  orders: Order[];
}

interface OrderResponse {
  order: Order | null;
}

interface OrderByNumberResponse {
  orderByNumber: Order | null;
}

interface OrdersByCustomerResponse {
  ordersByCustomer: Order[];
}

interface ConfirmedOrdersResponse {
  confirmedOrders: Order[];
}

/**
 * Hook to fetch orders for a company with optional status filter.
 */
export function useOrders(
  companyId: string | undefined,
  filters?: { status?: OrderStatus },
  options?: Omit<UseQueryOptions<Order[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('orders', { companyId, ...filters }),
    queryFn: async () => {
      if (!companyId) return [];
      const data = await fetchGraphQL<OrdersResponse>(ORDERS_QUERY, {
        companyId,
        status: filters?.status,
      });
      return data.orders;
    },
    enabled: !!companyId,
    ...options,
  });
}

/**
 * Hook to fetch a single order by ID.
 */
export function useOrder(
  id: string | undefined,
  options?: Omit<UseQueryOptions<Order | null, Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('order', { id }),
    queryFn: async () => {
      if (!id) return null;
      const data = await fetchGraphQL<OrderResponse>(ORDER_QUERY, { id });
      return data.order;
    },
    enabled: !!id,
    ...options,
  });
}

/**
 * Hook to fetch an order by order number.
 */
export function useOrderByNumber(
  companyId: string | undefined,
  orderNumber: string | undefined,
  options?: Omit<UseQueryOptions<Order | null, Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('orderByNumber', { companyId, orderNumber }),
    queryFn: async () => {
      if (!companyId || !orderNumber) return null;
      const data = await fetchGraphQL<OrderByNumberResponse>(ORDER_BY_NUMBER_QUERY, {
        companyId,
        orderNumber,
      });
      return data.orderByNumber;
    },
    enabled: !!companyId && !!orderNumber,
    ...options,
  });
}

/**
 * Hook to fetch orders by customer.
 */
export function useOrdersByCustomer(
  customerId: string | undefined,
  filters?: { status?: OrderStatus },
  options?: Omit<UseQueryOptions<Order[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('ordersByCustomer', { customerId, ...filters }),
    queryFn: async () => {
      if (!customerId) return [];
      const data = await fetchGraphQL<OrdersByCustomerResponse>(ORDERS_BY_CUSTOMER_QUERY, {
        customerId,
        status: filters?.status,
      });
      return data.ordersByCustomer;
    },
    enabled: !!customerId,
    ...options,
  });
}

/**
 * Hook to fetch confirmed orders ready for invoicing.
 */
export function useConfirmedOrders(
  companyId: string | undefined,
  options?: Omit<UseQueryOptions<Order[], Error>, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: createQueryKey('confirmedOrders', { companyId }),
    queryFn: async () => {
      if (!companyId) return [];
      const data = await fetchGraphQL<ConfirmedOrdersResponse>(CONFIRMED_ORDERS_QUERY, {
        companyId,
      });
      return data.confirmedOrders;
    },
    enabled: !!companyId,
    ...options,
  });
}
