// Simple Booking Store - Zustand store for quick/simple booking workflow

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { VATCode } from '@/types/vat';
import type {
  BankTransactionInput,
  GeneratedTransaction,
  SplitBookingLine,
} from '@/lib/accounting';

// =====================================================
// TYPES
// =====================================================

/**
 * Bank transaction with booking status
 */
export interface PendingBankTransaction extends BankTransactionInput {
  isBooked: boolean;
  bookedAt?: string;
  transactionId?: string; // Reference to created accounting transaction
}

/**
 * Favorite/quick account for fast selection
 */
export interface FavoriteAccount {
  id: string;
  accountId: string;
  accountNumber: string;
  accountName: string;
  defaultVATCode: VATCode;
  usageCount: number;
  lastUsed?: string;
}

/**
 * Booking modal state
 */
export interface BookingModalState {
  isOpen: boolean;
  type: 'simple' | 'split' | null;
  bankTransaction: PendingBankTransaction | null;
}

/**
 * Split booking working state
 */
export interface SplitBookingState {
  lines: SplitBookingLine[];
  remainingAmount: number;
}

// =====================================================
// STORE STATE
// =====================================================

interface SimpleBookingState {
  // Bank transactions
  pendingTransactions: PendingBankTransaction[];
  selectedBankAccountId: string | null;

  // Favorites
  favoriteAccounts: FavoriteAccount[];

  // Modal state
  modal: BookingModalState;

  // Split booking state
  splitState: SplitBookingState;

  // Preview
  preview: GeneratedTransaction | null;

  // Loading states
  isLoading: boolean;
  isSaving: boolean;

  // Actions - Bank Transactions
  setPendingTransactions: (transactions: PendingBankTransaction[]) => void;
  markAsBooked: (transactionId: string, accountingTransactionId: string) => void;
  setSelectedBankAccount: (accountId: string | null) => void;

  // Actions - Favorites
  addFavoriteAccount: (account: Omit<FavoriteAccount, 'id' | 'usageCount'>) => void;
  removeFavoriteAccount: (accountId: string) => void;
  incrementFavoriteUsage: (accountId: string) => void;
  updateFavoriteVATCode: (accountId: string, vatCode: VATCode) => void;

  // Actions - Modal
  openSimpleBooking: (transaction: PendingBankTransaction) => void;
  openSplitBooking: (transaction: PendingBankTransaction) => void;
  closeModal: () => void;

  // Actions - Split Booking
  addSplitLine: (line: SplitBookingLine) => void;
  updateSplitLine: (index: number, line: Partial<SplitBookingLine>) => void;
  removeSplitLine: (index: number) => void;
  clearSplitLines: () => void;

  // Actions - Preview
  setPreview: (preview: GeneratedTransaction | null) => void;

  // Actions - Loading
  setLoading: (loading: boolean) => void;
  setSaving: (saving: boolean) => void;

  // Computed
  getUnbookedTransactions: () => PendingBankTransaction[];
  getTopFavorites: (limit?: number) => FavoriteAccount[];
  getSplitRemainingAmount: () => number;

  // Reset
  resetStore: () => void;
}

// =====================================================
// INITIAL STATE
// =====================================================

const initialModalState: BookingModalState = {
  isOpen: false,
  type: null,
  bankTransaction: null,
};

const initialSplitState: SplitBookingState = {
  lines: [],
  remainingAmount: 0,
};

const initialState = {
  pendingTransactions: [],
  selectedBankAccountId: null,
  favoriteAccounts: [],
  modal: initialModalState,
  splitState: initialSplitState,
  preview: null,
  isLoading: false,
  isSaving: false,
};

// =====================================================
// STORE IMPLEMENTATION
// =====================================================

export const useSimpleBookingStore = create<SimpleBookingState>()(
  persist(
    (set, get) => ({
  ...initialState,

  // Bank Transactions
  setPendingTransactions: (transactions) =>
    set({ pendingTransactions: transactions }),

  markAsBooked: (transactionId, accountingTransactionId) =>
    set((state) => ({
      pendingTransactions: state.pendingTransactions.map((tx) =>
        tx.id === transactionId
          ? {
              ...tx,
              isBooked: true,
              bookedAt: new Date().toISOString(),
              transactionId: accountingTransactionId,
            }
          : tx
      ),
    })),

  setSelectedBankAccount: (accountId) =>
    set({ selectedBankAccountId: accountId }),

  // Favorites
  addFavoriteAccount: (account) =>
    set((state) => ({
      favoriteAccounts: [
        ...state.favoriteAccounts,
        {
          ...account,
          id: `fav-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
          usageCount: 0,
        },
      ],
    })),

  removeFavoriteAccount: (accountId) =>
    set((state) => ({
      favoriteAccounts: state.favoriteAccounts.filter((f) => f.accountId !== accountId),
    })),

  incrementFavoriteUsage: (accountId) =>
    set((state) => ({
      favoriteAccounts: state.favoriteAccounts.map((f) =>
        f.accountId === accountId
          ? {
              ...f,
              usageCount: f.usageCount + 1,
              lastUsed: new Date().toISOString(),
            }
          : f
      ),
    })),

  updateFavoriteVATCode: (accountId, vatCode) =>
    set((state) => ({
      favoriteAccounts: state.favoriteAccounts.map((f) =>
        f.accountId === accountId ? { ...f, defaultVATCode: vatCode } : f
      ),
    })),

  // Modal
  openSimpleBooking: (transaction) =>
    set({
      modal: {
        isOpen: true,
        type: 'simple',
        bankTransaction: transaction,
      },
      preview: null,
    }),

  openSplitBooking: (transaction) =>
    set({
      modal: {
        isOpen: true,
        type: 'split',
        bankTransaction: transaction,
      },
      splitState: {
        lines: [],
        remainingAmount: Math.abs(transaction.amount),
      },
      preview: null,
    }),

  closeModal: () =>
    set({
      modal: initialModalState,
      splitState: initialSplitState,
      preview: null,
    }),

  // Split Booking
  addSplitLine: (line) =>
    set((state) => {
      const newLines = [...state.splitState.lines, line];
      const totalAllocated = newLines.reduce((sum, l) => sum + Math.abs(l.amount), 0);
      const totalAmount = state.modal.bankTransaction
        ? Math.abs(state.modal.bankTransaction.amount)
        : 0;

      return {
        splitState: {
          lines: newLines,
          remainingAmount: Math.max(0, totalAmount - totalAllocated),
        },
      };
    }),

  updateSplitLine: (index, updates) =>
    set((state) => {
      const newLines = [...state.splitState.lines];
      if (index >= 0 && index < newLines.length) {
        newLines[index] = { ...newLines[index], ...updates };
      }

      const totalAllocated = newLines.reduce((sum, l) => sum + Math.abs(l.amount), 0);
      const totalAmount = state.modal.bankTransaction
        ? Math.abs(state.modal.bankTransaction.amount)
        : 0;

      return {
        splitState: {
          lines: newLines,
          remainingAmount: Math.max(0, totalAmount - totalAllocated),
        },
      };
    }),

  removeSplitLine: (index) =>
    set((state) => {
      const newLines = state.splitState.lines.filter((_, i) => i !== index);
      const totalAllocated = newLines.reduce((sum, l) => sum + Math.abs(l.amount), 0);
      const totalAmount = state.modal.bankTransaction
        ? Math.abs(state.modal.bankTransaction.amount)
        : 0;

      return {
        splitState: {
          lines: newLines,
          remainingAmount: Math.max(0, totalAmount - totalAllocated),
        },
      };
    }),

  clearSplitLines: () =>
    set((state) => ({
      splitState: {
        lines: [],
        remainingAmount: state.modal.bankTransaction
          ? Math.abs(state.modal.bankTransaction.amount)
          : 0,
      },
    })),

  // Preview
  setPreview: (preview) => set({ preview }),

  // Loading
  setLoading: (isLoading) => set({ isLoading }),
  setSaving: (isSaving) => set({ isSaving }),

  // Computed
  getUnbookedTransactions: () =>
    get().pendingTransactions.filter((tx) => !tx.isBooked),

  getTopFavorites: (limit = 5) =>
    [...get().favoriteAccounts]
      .sort((a, b) => b.usageCount - a.usageCount)
      .slice(0, limit),

  getSplitRemainingAmount: () => get().splitState.remainingAmount,

  // Reset
  resetStore: () => set(initialState),
    }),
    {
      name: 'simple-booking-favorites',
      // Only persist favoriteAccounts - transient state like modal/preview should not be persisted
      partialize: (state) => ({
        favoriteAccounts: state.favoriteAccounts,
      }),
    }
  )
);

// =====================================================
// SELECTOR HOOKS
// =====================================================

export const usePendingTransactions = () =>
  useSimpleBookingStore((state) => state.pendingTransactions);

export const useUnbookedTransactions = () =>
  useSimpleBookingStore((state) => state.getUnbookedTransactions());

export const useFavoriteAccounts = () =>
  useSimpleBookingStore((state) => state.favoriteAccounts);

export const useTopFavorites = (limit?: number) =>
  useSimpleBookingStore((state) => state.getTopFavorites(limit));

export const useBookingModal = () =>
  useSimpleBookingStore((state) => state.modal);

export const useSplitState = () =>
  useSimpleBookingStore((state) => state.splitState);

export const useBookingPreview = () =>
  useSimpleBookingStore((state) => state.preview);

export const useIsBookingSaving = () =>
  useSimpleBookingStore((state) => state.isSaving);
