import { useMutation, useQueryClient } from '@tanstack/react-query';
import { gql } from 'graphql-request';
import { fetchGraphQL, createQueryKey } from '../client';
import type { FiscalYear } from '@/types/periods';

// GraphQL Mutations
const CREATE_FISCAL_YEAR_MUTATION = gql`
  mutation CreateFiscalYear($input: CreateFiscalYearInput!) {
    createFiscalYear(input: $input) {
      id
      companyId
      name
      startDate
      endDate
      status
      openingBalancePosted
      closingDate
      closedBy
      createdAt
      updatedAt
    }
  }
`;

const CLOSE_FISCAL_YEAR_MUTATION = gql`
  mutation CloseFiscalYear($id: ID!) {
    closeFiscalYear(id: $id) {
      id
      status
      closingDate
      closedBy
      updatedAt
    }
  }
`;

const REOPEN_FISCAL_YEAR_MUTATION = gql`
  mutation ReopenFiscalYear($id: ID!) {
    reopenFiscalYear(id: $id) {
      id
      status
      reopenedDate
      reopenedBy
      updatedAt
    }
  }
`;

const LOCK_FISCAL_YEAR_MUTATION = gql`
  mutation LockFiscalYear($id: ID!) {
    lockFiscalYear(id: $id) {
      id
      status
      lockedDate
      lockedBy
      updatedAt
    }
  }
`;

// Input types
export interface CreateFiscalYearInput {
  companyId: string;
  name: string;
  startDate: string; // ISO date string
  endDate: string; // ISO date string
  isFirstFiscalYear?: boolean;
  isReorganization?: boolean;
}

// Response types
interface FiscalYearResponse {
  id: string;
  companyId: string;
  name: string;
  startDate: string;
  endDate: string;
  status: string;
  openingBalancePosted: boolean;
  closingDate?: string;
  closedBy?: string;
  reopenedDate?: string;
  reopenedBy?: string;
  lockedDate?: string;
  lockedBy?: string;
  createdAt: string;
  updatedAt: string;
}

interface CreateFiscalYearResponse {
  createFiscalYear: FiscalYearResponse;
}

interface CloseFiscalYearResponse {
  closeFiscalYear: FiscalYearResponse;
}

interface ReopenFiscalYearResponse {
  reopenFiscalYear: FiscalYearResponse;
}

interface LockFiscalYearResponse {
  lockFiscalYear: FiscalYearResponse;
}

// Transform response to frontend type
function transformFiscalYear(fy: FiscalYearResponse): FiscalYear {
  return {
    id: fy.id,
    companyId: fy.companyId,
    name: fy.name,
    startDate: fy.startDate,
    endDate: fy.endDate,
    status: fy.status.toLowerCase() as 'open' | 'closed' | 'locked',
    openingBalancePosted: fy.openingBalancePosted,
    closingDate: fy.closingDate,
    closedBy: fy.closedBy,
    reopenedDate: fy.reopenedDate,
    reopenedBy: fy.reopenedBy,
    lockedDate: fy.lockedDate,
    lockedBy: fy.lockedBy,
    createdAt: fy.createdAt,
    updatedAt: fy.updatedAt,
  };
}

/**
 * Hook to create a new fiscal year.
 */
export function useCreateFiscalYear() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (input: CreateFiscalYearInput) => {
      const data = await fetchGraphQL<CreateFiscalYearResponse>(
        CREATE_FISCAL_YEAR_MUTATION,
        { input }
      );
      return transformFiscalYear(data.createFiscalYear);
    },
    onSuccess: (newFiscalYear) => {
      // Invalidate fiscal years query to refetch
      queryClient.invalidateQueries({
        queryKey: createQueryKey('fiscalYears', { companyId: newFiscalYear.companyId }),
      });
    },
  });
}

/**
 * Hook to close a fiscal year.
 */
export function useCloseFiscalYear() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const data = await fetchGraphQL<CloseFiscalYearResponse>(
        CLOSE_FISCAL_YEAR_MUTATION,
        { id }
      );
      return transformFiscalYear(data.closeFiscalYear);
    },
    onSuccess: (updatedFiscalYear) => {
      queryClient.invalidateQueries({
        queryKey: createQueryKey('fiscalYears', { companyId: updatedFiscalYear.companyId }),
      });
    },
  });
}

/**
 * Hook to reopen a closed fiscal year.
 */
export function useReopenFiscalYear() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const data = await fetchGraphQL<ReopenFiscalYearResponse>(
        REOPEN_FISCAL_YEAR_MUTATION,
        { id }
      );
      return transformFiscalYear(data.reopenFiscalYear);
    },
    onSuccess: (updatedFiscalYear) => {
      queryClient.invalidateQueries({
        queryKey: createQueryKey('fiscalYears', { companyId: updatedFiscalYear.companyId }),
      });
    },
  });
}

/**
 * Hook to permanently lock a fiscal year.
 */
export function useLockFiscalYear() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const data = await fetchGraphQL<LockFiscalYearResponse>(
        LOCK_FISCAL_YEAR_MUTATION,
        { id }
      );
      return transformFiscalYear(data.lockFiscalYear);
    },
    onSuccess: (updatedFiscalYear) => {
      queryClient.invalidateQueries({
        queryKey: createQueryKey('fiscalYears', { companyId: updatedFiscalYear.companyId }),
      });
    },
  });
}
