import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { applyDiscount, type Coupon } from './discount'
import { calcInterest, type CreditCard } from './payment'
import type { PaymentMethod } from '@repo/ui/routes/orders/data'
import type { Enrollment } from '../_.$orgid.enrollments.add/data'
import type { Item } from './bulk'

export type WizardState = {
  index: number
  kind: 'bulk' | 'assigned'
  items: Item[]
  enrollments: Enrollment[]
  coupon?: Coupon
  installments?: number
  payment_method?: PaymentMethod
  credit_card?: CreditCard
}

type Summary = {
  subtotal: number
  discount: number
  interest_amount: number
  total: number
}

export type WizardStore = WizardState & {
  setIndex: (index: number) => void
  setKind: (kind: 'bulk' | 'assigned') => void
  update: (data: Partial<WizardState>) => void
  reset: () => void
  summary: () => Summary
}

const emptyWizard: WizardState = {
  index: 0,
  kind: 'bulk',
  items: [],
  enrollments: []
}

export const useWizardStore = create<WizardStore>()(
  persist(
    (set, get) => ({
      ...emptyWizard,

      setIndex: (index) => set({ index }),
      setKind: (kind) => set({ kind }),

      summary: () => {
        const { items, coupon, credit_card, installments } = get()
        const subtotal = items.reduce(
          (acc, { course, quantity }) =>
            acc +
            (course?.unit_price || 0) *
              (Number.isFinite(quantity) && quantity > 0 ? quantity : 1),
          0
        )
        const discount = coupon
          ? applyDiscount(subtotal, coupon.amount, coupon.type) * -1
          : 0

        const total = subtotal > 0 ? subtotal + discount : 0
        const interest_amount =
          credit_card && typeof installments === 'number' && installments > 1
            ? calcInterest(total, installments) - total
            : 0

        return {
          subtotal,
          discount,
          interest_amount,
          total: total + interest_amount
        }
      },

      update: (data) =>
        set((state) => {
          if (data.enrollments) {
            const items = Object.values(
              data.enrollments.reduce<Record<string, Item>>(
                (acc, { course }) => {
                  const { id } = course

                  acc[id] ??= { course, quantity: 0 }
                  acc[id].quantity++

                  return acc
                },
                {}
              )
            )

            return {
              ...state,
              ...data,
              items
            }
          }

          if (data.items) {
            const items = Object.values(
              data.items.reduce<Record<string, Item>>((acc, item) => {
                const id = item.course.id

                if (!acc[id]) {
                  acc[id] = { ...item }
                } else {
                  acc[id].quantity += item.quantity
                }

                return acc
              }, {})
            )

            return {
              ...state,
              ...data,
              items,
              enrollments: []
            }
          }

          return {
            ...state,
            ...data
          }
        }),

      reset: () => set({ ...emptyWizard })
    }),
    {
      name: 'wizard_cart'
    }
  )
)
