import * as babel from '@babel/core';

export interface IPhysicsConfig {
    gravity: IVec3Like; // （0，-10， 0）
    allowSleep: boolean; // true
    sleepThreshold: number; // 0.1，最小 0
    autoSimulation: boolean; // true
    fixedTimeStep: number; // 1 / 60 ，最小 0
    maxSubSteps: number; // 1，最小 0
    defaultMaterial?: string; // 物理材质 uuid
    useNodeChains: boolean; // true
    collisionMatrix: ICollisionMatrix;
    physicsEngine: string;
    physX?: {
        notPackPhysXLibs: boolean;
        multiThread: boolean;
        subThreadCount: number;
        epsilon: number;
    };
}

export type IConsoleType = 'log' | 'warn' | 'error' | 'debug';

export interface IBuildOptionBase {
    // packAutoAtlas: boolean;
    taskName: string;
    platform: Platform;
    scenes: IBuildSceneItem[];
    skipCompressTexture: boolean;
    sourceMaps: boolean;
    experimentalEraseModules: boolean;
    bundleCommonChunk: boolean;

    startScene: string;
    // 构建后的游戏文件夹生成的路径
    buildPath: string;
    debug: boolean;
    inlineSpriteFrames: boolean;
    md5Cache: boolean;

    // bundle 设置
    mainBundleCompressionType: BundleCompressionType;
    mainBundleIsRemote: boolean;
    useBuiltinServer: boolean; // 使用内置的服务器地址，实验性功能
    server?: string; // 服务器地址
    startSceneAssetBundle: boolean; // 配置初始场景为远程包
    bundleCommonJs?: string;

    // 移除远程包 Bundle 的脚本, 小游戏平台将会自动勾选
    moveRemoteBundleScript: boolean;

    // 项目设置
    includeModules?: string[];
    renderPipeline?: string;
    designResolution?: IBuildDesignResolution;
    physicsConfig?: IPhysicsConfig;
    flags?: Record<string, boolean>;
    customLayers: { name: string, value: number }[];
    sortingLayers: { id: number, name: string, value: number }[];
    macroConfig?: Record<string, any>

    // 是否使用自定义插屏选项
    useSplashScreen?: boolean;
    splashScreen: ISplashSetting;

    /**
     * 是否是预览进程发送的构建请求。
     * @default false
     */
    preview?: boolean;

    buildMode?: 'normal' | 'bundle' | 'script';
}

/**
 * 构建所需的完整参数
 */
export interface IBuildTaskOption extends IBuildOptionBase {
    taskId?: string; // 指定构建任务 id，可选
    logDest?: string; // 任务的指定构建输出地址，可选

    name: string;

    outputName: string;
    taskName: string;
    polyfills?: IPolyFills;
    nextStages?: string[];
    resolution: {
        width: number;
        height: number;
        policy: number;
    }

    // 构建阶段性任务绑定分组
    buildStageGroup?: Record<string, string[]>;

    packages?: Record<string, any>;
    id?: string; // 手动配置构建任务 id
    // recompileConfig?: IRecompileConfig;

    // 构建 Bundle 的指定包含传参，未传递时按照项目内所有 Bundle 的原始配置打包
    // name 有一定的计算规则，作为选填项
    bundleConfigs?: IBundleOptions[];
    buildBundleOnly?: boolean; // 仅构建 Bundle

    // 一些偏好设置选项
    useBuildAssetCache?: boolean;
    useBuildEngineCache?: boolean;
    useBuildTextureCompressCache?: boolean;
    useBuildAutoAtlasCache?: boolean;
    __version__?: string;
}

export type UUID = string;

export interface ISplashSetting {
    displayRatio: number;
    totalTime: number;
    watermarkLocation: 'default' | 'topLeft' | 'topRight' | 'topCenter' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
    autoFit: boolean;

    logo?: {
        type: 'default' | 'none' | 'custom';
        image?: string;
        base64?: string;
    }
    background?: {
        type: 'default' | 'color' | 'custom';
        color?: ISplashBackgroundColor;
        image?: string;
        base64?: string;
    }
}

export interface ISplashBackgroundColor {
    x: number;
    y: number;
    z: number;
    w: number ;
}

export interface ICustomJointTextureLayout {
    textureLength: number;
    contents: IChunkContent[];
}

export interface IChunkContent {
    skeleton: null | string;
    clips: string[];
}

/**
 * 构建使用的设计分辨率数据
 */
export interface IBuildDesignResolution {
    height: number;
    width: number;
    fitWidth?: boolean;
    fitHeight?: boolean;
    policy?: number;
}

/**
 * 构建使用的场景的数据
 */
export interface IBuildSceneItem {
    url: string;
    uuid: string;
}

export interface IPolyFills {
    /**
     * True if async functions polyfills(i.e. regeneratorRuntime) needs to be included.
     * You need to turn on this field if you want to use async functions in language.
     */
    asyncFunctions?: boolean;

    /**
     * If true, [core-js](https://github.com/zloirock/core-js) polyfills are included.
     * The default options of [core-js-builder](https://github.com/zloirock/core-js/tree/master/packages/core-js-builder)
     * will be used to build the core-js.
     */
    coreJs?: boolean;

    targets?: string;
}

export interface IBuildSystemJsOption {
    dest: string;
    platform: string;
    debug: boolean;
    sourceMaps: boolean;
    hotModuleReload?: boolean;
}

interface ICompressPresetConfig {
    name: string;
    options: Record<ITextureCompressPlatform, Record<ITextureCompressType, { quality: number | string }>>;
}
export interface ITextureCompressConfigs {
    userPreset: Record<string, ICompressPresetConfig>;
    genMipmaps: boolean;
    customConfigs: Record<string, ICompressPresetConfig>;
}

// **************************** options *******************************************
export type Platform =
    | 'web-desktop'
    | 'web-mobile'
    | 'wechatgame'
    | 'wechatprogram'
    | 'oppo-mini-game'
    | 'vivo-mini-game'
    | 'huawei-quick-game'
    | 'alipay-mini-game'
    | 'taobao-creative-app'
    | 'taobao-mini-game'
    | 'mac'
    | 'ios'
    | 'linux'
    // | 'ios-app-clip'
    | 'android'
    | 'ohos'
    | 'openharmony'
    | 'windows'
    | 'xiaomi-quick-game'
    | 'baidu-mini-game'
    | 'bytedance-mini-game'
    | 'cocos-play'
    | 'huawei-agc'
    | 'link-sure'
    | 'qtt'
    | 'fb-instant-games'
    | 'cocos-runtime'
    | 'xr-meta'
    | 'xr-huaweivr'
    | 'xr-pico'
    | 'xr-rokid'
    | 'xr-monado'
    | 'ar-android'
    | 'ar-ios'
    | 'xr-spaces'
    | 'xr-seed'
    | 'online'
    | 'xr-gsxr'
    | 'xr-yvr'
    | 'xr-htc'
    | 'xr-iqiyi'
    | 'xr-skyworth'
    | 'xr-ffalcon'
    | 'xr-nreal'
    | 'xr-inmo'
    | 'xr-lenovo'
    ;
export type BundleCompressionType = 'none' | 'merge_dep' | 'merge_all_json' | 'subpackage' | 'zip';

export type IModules = 'esm' | 'commonjs' | 'systemjs';
export interface ITransformOptions {
    importMapFormat: IModules;
    plugins?: babel.PluginItem[];
}

export type ITaskState = 'waiting' | 'success' | 'failure' | 'cancel' | 'processing' | 'none';

export interface ITaskItemJSON {
    id: string;
    progress: number;
    state: ITaskState;
    message: string;
    time: string;
}

export interface IBuildTaskItemJSON extends ITaskItemJSON {
    stage: 'build' | string;
    options: IBuildTaskOption;
    dirty: boolean;
    rawOptions?: IBuildTaskOption;
    type: 'build',
}

export type IOrientation = 'auto' | 'landscape' | 'portrait';