//
//  OrdersViewModel.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import Foundation
import Observation

@MainActor
@Observable
/// 订单页面 ViewModel，管理订单列表、核销列表、筛选条件和手动核销流程。
final class OrdersViewModel {
    var selectedEntry: OrdersEntry = .storeOrders
    var selectedStatus = 0
    var searchPhone = ""
    var filterStartDate: Date?
    var filterEndDate: Date?
    private(set) var loading = false
    private(set) var loadingMore = false
    private(set) var isVerifying = false
    private(set) var currentVerifyingOrderNumber: String?

    private(set) var storeOrders: [OrderEntity] = []
    private(set) var storeTotal = 0
    private(set) var storePage = 1
    private(set) var storeHasMore = false

    private(set) var writeOffOrders: [WriteOffOrderItem] = []
    private(set) var writeOffTotal = 0
    private(set) var writeOffPage = 1
    private(set) var writeOffHasMore = false

    /// 返回去除首尾空白后的手机号搜索值。
    var normalizedPhone: String? {
        let text = searchPhone.trimmingCharacters(in: .whitespacesAndNewlines)
        return text.isEmpty ? nil : text
    }

    /// 根据当前子入口刷新对应列表。
    func reload(api: OrderServing, scenicId: Int?, storeId: Int? = nil, roleId: Int?, showLoading: Bool = true) async throws {
        switch selectedEntry {
        case .storeOrders:
            try await reloadStoreOrders(api: api, scenicId: scenicId, roleId: roleId, showLoading: showLoading)
        case .verificationOrders:
            try await reloadWriteOffOrders(api: api, scenicId: scenicId, storeId: storeId, showLoading: showLoading)
        }
    }

    /// 刷新订单管理列表，缺少景区时清空旧数据。
    func reloadStoreOrders(api: OrderServing, scenicId: Int?, roleId: Int?, showLoading: Bool = true) async throws {
        guard let scenicId else {
            storeOrders = []
            storeTotal = 0
            storePage = 1
            storeHasMore = false
            return
        }

        if showLoading { loading = true }
        defer { if showLoading { loading = false } }

        let result = try await api.orderList(
            scenicId: scenicId,
            page: 1,
            pageSize: pageSize,
            orderStatus: orderStatusQuery,
            userPhone: normalizedPhone,
            startTime: startTimeQuery,
            endTime: endTimeQuery,
            isRefined: refinedQuery,
            isScenicAdmin: roleId == 53
        )
        storeOrders = result.list
        storeTotal = result.total
        storePage = 1
        storeHasMore = storeOrders.count < result.total && !result.list.isEmpty
    }

    /// 加载订单管理下一页。
    func loadMoreStoreOrders(api: OrderServing, scenicId: Int?, roleId: Int?) async throws {
        guard !loadingMore, storeHasMore, let scenicId else { return }
        loadingMore = true
        defer { loadingMore = false }

        let nextPage = storePage + 1
        let result = try await api.orderList(
            scenicId: scenicId,
            page: nextPage,
            pageSize: pageSize,
            orderStatus: orderStatusQuery,
            userPhone: normalizedPhone,
            startTime: startTimeQuery,
            endTime: endTimeQuery,
            isRefined: refinedQuery,
            isScenicAdmin: roleId == 53
        )
        storeOrders.append(contentsOf: result.list)
        storeTotal = result.total
        storePage = nextPage
        storeHasMore = storeOrders.count < result.total && !result.list.isEmpty
    }

    /// 刷新核销订单列表，缺少景区时清空旧数据。
    func reloadWriteOffOrders(api: OrderServing, scenicId: Int?, storeId: Int? = nil, showLoading: Bool = true) async throws {
        guard let scenicId else {
            writeOffOrders = []
            writeOffTotal = 0
            writeOffPage = 1
            writeOffHasMore = false
            return
        }

        if showLoading { loading = true }
        defer { if showLoading { loading = false } }

        let result = try await api.writeOffList(scenicId: scenicId, storeId: storeId, page: 1, pageSize: pageSize)
        writeOffOrders = result.list
        writeOffTotal = result.total
        writeOffPage = 1
        writeOffHasMore = writeOffOrders.count < result.total && !result.list.isEmpty
    }

    /// 加载核销订单下一页。
    func loadMoreWriteOffOrders(api: OrderServing, scenicId: Int?, storeId: Int? = nil) async throws {
        guard !loadingMore, writeOffHasMore, let scenicId else { return }
        loadingMore = true
        defer { loadingMore = false }

        let nextPage = writeOffPage + 1
        let result = try await api.writeOffList(scenicId: scenicId, storeId: storeId, page: nextPage, pageSize: pageSize)
        writeOffOrders.append(contentsOf: result.list)
        writeOffTotal = result.total
        writeOffPage = nextPage
        writeOffHasMore = writeOffOrders.count < result.total && !result.list.isEmpty
    }

    /// 手动核销订单，并在成功后刷新核销列表。
    func verify(api: OrderServing, scenicId: Int, storeId: Int? = nil, orderNumber: String) async throws {
        guard !isVerifying else { return }

        isVerifying = true
        currentVerifyingOrderNumber = orderNumber
        defer {
            isVerifying = false
            currentVerifyingOrderNumber = nil
        }

        try await api.writeOff(orderNumber: orderNumber)
        let refreshed = try await api.writeOffList(scenicId: scenicId, storeId: storeId, page: 1, pageSize: pageSize)
        writeOffOrders = refreshed.list
        writeOffTotal = refreshed.total
        writeOffPage = 1
        writeOffHasMore = writeOffOrders.count < refreshed.total && !refreshed.list.isEmpty
    }

    /// 解析扫码结果并返回当前核销列表中的匹配订单。
    func matchedWriteOffOrder(for rawCode: String) -> (orderNumber: String, matched: WriteOffOrderItem?)? {
        guard let orderNumber = OrderNumberParser.parse(rawCode) else {
            return nil
        }
        let matched = writeOffOrders.first {
            $0.orderNumber.caseInsensitiveCompare(orderNumber) == .orderedSame
        }
        return (matched?.orderNumber ?? orderNumber, matched)
    }

    /// 根据订单号查找当前核销列表中的订单。
    func writeOffOrder(matching orderNumber: String) -> WriteOffOrderItem? {
        writeOffOrders.first {
            $0.orderNumber.caseInsensitiveCompare(orderNumber) == .orderedSame
        }
    }

    /// 用于测试重复提交场景的内部状态设置。
    func markVerifyingForTests(orderNumber: String) {
        isVerifying = true
        currentVerifyingOrderNumber = orderNumber
    }

    private let pageSize = 20

    private var orderStatusQuery: Int? {
        selectedStatus > 0 ? selectedStatus : nil
    }

    private var startTimeQuery: String? {
        filterStartDate.map { Self.dayFormatter.string(from: $0) }
    }

    private var endTimeQuery: String? {
        filterEndDate.map { Self.dayFormatter.string(from: $0) }
    }

    private var refinedQuery: Int? {
        switch selectedStatus {
        case -1:
            return 1
        case -2:
            return 2
        default:
            return nil
        }
    }

    private static let dayFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .gregorian)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
}
