import { action, computed, makeObservable, observable } from 'mobx'
import urlGenerator from '$ustoreinternal/services/urlGenerator'
import DraftItemModel from './DraftItemModel'

class DraftsModel {
  static DRAFT_SECTIONS = {
    SAVED: 'saved',
    LATEST: 'latest',
  }

  constructor({ UStoreProvider, storeBaseUrl, storeApiUrl, navigate, maxDrafts = 3 }) {
    this._uStoreProvider = UStoreProvider
    this._storeData = { navigate, storeBaseUrl, storeApiUrl }
    this.maxDrafts = maxDrafts

    this.latestDrafts = []
    this.savedDrafts = []
    this.searchQuery = ''
    this.initiated = false
    this.loading = false
    this.savedSectionExpanded = true
    this.latestSectionExpanded = true
    this.successMessage = null
    this.successMessageItemId = null

    makeObservable(this, {
      latestDrafts: observable,
      savedDrafts: observable,
      searchQuery: observable,
      initiated: observable,
      loading: observable,
      savedSectionExpanded: observable,
      latestSectionExpanded: observable,
      successMessage: observable,
      successMessageItemId: observable,
      init: action,
      loadDraftsFromApi: action,
      setSearchQuery: action,
      toggleSection: action,
      deleteItem: action,
      deleteAllInSection: action,
      saveItem: action,
      moveDraftToSaved: action,
      setSuccessMessage: action,
      clearSuccessMessage: action,
      filteredSavedDrafts: computed,
      filteredLatestDrafts: computed,
      savedDraftsCount: computed,
      latestDraftsCount: computed,
      filteredSavedCount: computed,
      filteredLatestCount: computed,
      isEmpty: computed,
    })
  }

  async init() {
    this.initiated = false
    this.loading = true
    try {
      await this.loadDraftsFromApi()
    } catch (error) {
      throw error
    } finally {
      this.initiated = true
      this.loading = false
    }
  }

  async loadDraftsFromApi() {
    const response = await this._uStoreProvider.api.orders.getDraftItems()

    this.savedDrafts = (response.SavedDrafts || []).map(
      item => this.convertToDraftItemModel(item, DraftsModel.DRAFT_SECTIONS.SAVED)
    )

    this.latestDrafts = (response.LatestDrafts || []).map(
      item => this.convertToDraftItemModel(item, DraftsModel.DRAFT_SECTIONS.LATEST)
    )
  }

  convertToDraftItemModel(item, section) {
    let thumbnailUrl = null
    if (item.Thumbnail?.Url) {
      const cleanThumbnailPath = item.Thumbnail.Url.startsWith('/')
        ? item.Thumbnail.Url.substring(1)
        : item.Thumbnail.Url
      thumbnailUrl = `${this._storeData.storeApiUrl}/${cleanThumbnailPath}`
    }

    return new DraftItemModel({
      draftsModel: this,
      section,
      orderItemId: item.OrderItemID,
      orderItemFriendlyId: item.OrderItemFriendlyID,
      quantity: item.Quantity,
      description: item.Description,
      editUrl: urlGenerator.get({ page: 'products' }).replace('/products', item.EditUrl),
      creationDate: item.CreationDate,
      thumbnailUrl,
      product: {
        productId: item.Product?.ProductID,
        name: item.Product?.Name,
        catalogNumber: item.Product?.CatalogNumber,
        unit: item.Product?.Unit,
        isAvailable: item.Product?.IsAvailable !== false,
      },
      subItems: (item.SubItems || []).map(subItem => ({
        product: {
          productId: subItem.Product?.ProductID,
          name: subItem.Product?.Name,
          catalogNumber: subItem.Product?.CatalogNumber,
          unit: subItem.Product?.Unit,
          isAvailable: subItem.Product?.IsAvailable !== false,
        },
        quantity: subItem.Quantity,
      })),
      validations: item.Validations || [],
    })
  }

  setSearchQuery(query) {
    this.searchQuery = query.toLowerCase().trim()
  }

  toggleSection(section) {
    if (section === DraftsModel.DRAFT_SECTIONS.SAVED) {
      this.savedSectionExpanded = !this.savedSectionExpanded
    } else {
      this.latestSectionExpanded = !this.latestSectionExpanded
    }
  }

  async deleteItem(item, options = {}) {
    await this._uStoreProvider.api.orders.clearDrafts([item.orderItemId])

    if (options.deferRemove) {
      return
    }

    this.removeItemFromLists(item)
  }

  removeItemFromLists(item) {
    if (item.section === DraftsModel.DRAFT_SECTIONS.SAVED) {
      this.savedDrafts = this.savedDrafts.filter(d => d.orderItemId !== item.orderItemId)
    } else {
      this.latestDrafts = this.latestDrafts.filter(d => d.orderItemId !== item.orderItemId)
    }
  }

  async deleteAllInSection(section) {
    const items = section === DraftsModel.DRAFT_SECTIONS.SAVED
      ? this.filteredSavedDrafts
      : this.filteredLatestDrafts
    const ids = items.map(item => item.orderItemId)
    if (ids.length === 0) return

    await this._uStoreProvider.api.orders.clearDrafts(ids)

    if (section === DraftsModel.DRAFT_SECTIONS.SAVED) {
      this.savedDrafts = this.savedDrafts.filter(d => !ids.includes(d.orderItemId))
    } else {
      this.latestDrafts = this.latestDrafts.filter(d => !ids.includes(d.orderItemId))
    }
  }

  async saveItem(item, description, options = {}) {
    await this._uStoreProvider.api.orders.saveDraftItem(item.orderItemId, description)
    if (!options.deferMove) {
      if (item.section === DraftsModel.DRAFT_SECTIONS.LATEST) {
        this.moveDraftToSaved(item, description)
      } else {
        item.description = description
      }
    }
  }

  moveDraftToSaved(item, description) {
    item.description = description
    item.section = DraftsModel.DRAFT_SECTIONS.SAVED
    this.latestDrafts = this.latestDrafts.filter(d => d.orderItemId !== item.orderItemId)
    this.savedDrafts = [item, ...this.savedDrafts]
    this.setSuccessMessage(item.orderItemId)
  }

  setSuccessMessage(itemId) {
    this.successMessageItemId = itemId
    this.successMessage = true
    setTimeout(() => this.clearSuccessMessage(), 3000)
  }

  clearSuccessMessage() {
    this.successMessage = null
    this.successMessageItemId = null
  }

  navigate(url) {
    this._storeData.navigate(url)
  }

  get storeApiUrl() {
    return this._storeData.storeApiUrl
  }

  get filteredSavedDrafts() {
    if (!this.searchQuery) return this.savedDrafts
    return this.savedDrafts.filter(item =>
      item.product.name?.toLowerCase().includes(this.searchQuery) ||
      (item.description && item.description.toLowerCase().includes(this.searchQuery))
    )
  }

  get filteredLatestDrafts() {
    if (!this.searchQuery) return this.latestDrafts
    return this.latestDrafts.filter(item =>
      item.product.name?.toLowerCase().includes(this.searchQuery) ||
      (item.description && item.description.toLowerCase().includes(this.searchQuery))
    )
  }

  get savedDraftsCount() {
    return this.savedDrafts.length
  }

  get latestDraftsCount() {
    return this.latestDrafts.length
  }

  get filteredSavedCount() {
    return this.filteredSavedDrafts.length
  }

  get filteredLatestCount() {
    return this.filteredLatestDrafts.length
  }

  get isEmpty() {
    return this.savedDraftsCount === 0 && this.latestDraftsCount === 0
  }
}

export default DraftsModel
