import { EntryBase } from '../ContractBase/EntryBase'
import type { PrintContainer } from '../../Platform/Print/PrintContainer'
import type { Message } from '../../Communication/Message'
import { ContractManager } from '../Contracts/ContractManager'
import { PlatformLogger } from '../../Platform/Common/LogSystem'

/**
 * 打印逻辑入口(抽象类)
 */
export abstract class PrintflowEntry extends EntryBase {
    /**
     * 创建打印列表，抽象成交易自身定制
     */
    public abstract GeneratePrintList(): PrintContainer[]

    /**
     * 预处理过程
     */
    public abstract PreviewPrintflow(): boolean

    protected override OnLoadData(changed: boolean): boolean {
        // 触发无纸化操作
        return this.PageData.TradeAPIs.RaisePaperless(this.MessageData)
    }

    /**
     * 触发打印流程
     * @param stash 是否存储打印数据
     */
    internal RaisePrintflow(stash: boolean = true): boolean {
        const flow = this
        const page = flow.PageData
        const message = flow.MessageData
        
        try {
            // stash数据
            if (stash && !this.StashPrintData()) {
                return false
            }

            // 主流程执行,产生打印清单
            const printList = flow.GeneratePrintList()
            if (printList.length === 0) {
                return true
            }

            return ContractManager.RaisePrint(page, message, printList)
        } catch (ex) {
            page.TradeAPIs.ShowErrorMessageBox(`RaisePrintflow:创建打印清单发生异常！\n${ex.message}`)
            PlatformLogger.SystemErrorInfo("RaisePrintflow:创建打印清单发生异常！", ex)
            return false
        }
    }

    /**
     * 存储页面打印信息，以系统流水作为key
     */
    protected StashPrintData(): boolean {
        if (!this.PageData.CheckLoginStatus()) return false
        
        // 触发存储，异步操作
        this.StashPage()
        
        // 执行预处理
        return this.PreviewPrintflow()
    }

    /**
     * 内部登记实现
     */
    private StashPage(): void {
        try {
            // 开关检查
            if (!ServiceSettings.IsRecordPrintData) {
                return
            }

            // 存入到总线自定义项中
            const id = this.PageData.TradeInfo.SystemSerialNumber
            const message = this.MessageData
            
            if (message) {
                message.IsMainTrade = true
                message.SerialNumber = id
            }

            // 流程对象存入到总线，方便后续恢复使用
            this.PageData.TradeBus["PrintflowEntry"] = this.constructor.name

            // 上送数据
            const dll = `${PlatformSettings.PagesDirectory}\\${this.PageData.constructor.name}.dll`
            const fullName = this.PageData.constructor.name
            const printAttr = this.PageData.GetPrintAttributes()
            const json = printAttr.Serialize()
            const bus = CommonFunction.ChangeDicToStr(this.PageData.GetTradeInfoData().TradeBus.Serialize())

            // 异步触发，防止产生性能影响
            setTimeout(() => {
                PrintManagerHandle.RecordPrintExt(id, dll, fullName, json, bus)
            }, 0)
            
        } catch (ex) {
            PlatformLogger.SystemErrorInfo("StashPage:保存页面信息发生异常！", ex)
        }
    }
}

// Vue组合式API封装
export const usePrintflowEntry = () => {
    return {
        PrintflowEntry
    }
}

// 辅助类型
interface ServiceSettings {
    IsRecordPrintData: boolean
}

interface PlatformSettings {
    PagesDirectory: string
}

interface CommonFunction {
    ChangeDicToStr(dict: Record<string, string>): string
}

interface PrintManagerHandle {
    RecordPrintExt(id: string, dll: string, fullName: string, json: string, bus: string): void
}