/// <reference path="./global.d.ts" />

// 打开设置界面时触发

async function onSettingWindowCreated (view: Element) {
  window.llonebot.log('setting window created')
  const isEmpty = (value: any) => value === undefined || value === null || value === ''
  const config = await window.llonebot.getConfig()
  const httpClass = 'http'
  const httpPostClass = 'http-post'
  const wsClass = 'ws'
  const reverseWSClass = 'reverse-ws'
  const llonebotError = await window.llonebot.getError()
  window.llonebot.log('获取error' + JSON.stringify(llonebotError))

  function createHttpHostEleStr (host: string) {
    const eleStr = `
            <setting-item data-direction="row" class="hostItem vertical-list-item ${httpPostClass}">
                <h2>HTTP事件上报地址(http)</h2>
                <input class="httpHost input-text" type="text" value="${host}" 
                style="width:60%;padding: 5px"
                placeholder="如:http://127.0.0.1:8080/onebot/v11/http"/>
            </setting-item>
            `
    return eleStr
  }

  function createWsHostEleStr (host: string) {
    const eleStr = `
            <setting-item data-direction="row" class="hostItem vertical-list-item ${reverseWSClass}">
                <h2>反向websocket地址:</h2>
                <input class="wsHost input-text" type="text" value="${host}" 
                style="width:60%;padding: 5px"
                placeholder="如: ws://127.0.0.1:5410/onebot"/>
            </setting-item>
            `
    return eleStr
  }

  let httpHostsEleStr = ''
  for (const host of config.ob11.httpHosts) {
    httpHostsEleStr += createHttpHostEleStr(host)
  }

  let wsHostsEleStr = ''
  for (const host of config.ob11.wsHosts) {
    wsHostsEleStr += createWsHostEleStr(host)
  }

  const html = `
    <div class="config_view llonebot">
        <setting-section>
            <setting-panel id="llonebotError" style="display:${llonebotError.ffmpegError || llonebotError.otherError ? '' : 'none'}">
                <setting-item id="ffmpegError" data-direction="row" 
                    style="diplay:${llonebotError.ffmpegError ? '' : 'none'}"
                    class="hostItem vertical-list-item">
                    <setting-text data-type="secondary" class="err-content">${llonebotError.ffmpegError}</setting-text>
                </setting-item>
                <setting-item id="otherError" data-direction="row" 
                    style="diplay:${llonebotError.otherError ? '' : 'none'}"
                    class="hostItem vertical-list-item">
                    <setting-text data-type="secondary" class="err-content">${llonebotError.otherError}</setting-text>
                </setting-item>
            </setting-panel>
            <setting-panel>
                <setting-list class="wrap">
                    <setting-item data-direction="row" class="hostItem vertical-list-item">
                        <div>
                            <div>启用HTTP服务</div>
                        </div>
                        <setting-switch id="http" ${config.ob11.enableHttp ? 'is-active' : ''}></setting-switch>
                    </setting-item>
                    <setting-item class="vertical-list-item ${httpClass}" data-direction="row" style="display: ${config.ob11.enableHttp ? '' : 'none'}">
                        <setting-text>HTTP监听端口</setting-text>
                        <input id="httpPort" type="number" value="${config.ob11.httpPort}"/>
                    </setting-item>
                    <setting-item data-direction="row" class="hostItem vertical-list-item">
                        <div>
                            <div>启用HTTP事件上报</div>
                        </div>
                        <setting-switch id="httpPost" ${config.ob11.enableHttpPost ? 'is-active' : ''}></setting-switch>
                    </setting-item>
                    <div class="${httpPostClass}" style="display: ${config.ob11.enableHttpPost ? '' : 'none'}">
                        <div >
                            <button id="addHttpHost" class="q-button">添加HTTP POST上报地址</button>
                        </div>
                        <div id="httpHostItems">
                            ${httpHostsEleStr}
                        </div>
                    </div>
                    <setting-item data-direction="row" class="hostItem vertical-list-item">
                        <div>
                            <div>启用正向Websocket协议</div>
                        </div>
                        <setting-switch id="websocket" ${config.ob11.enableWs ? 'is-active' : ''}></setting-switch>
                    </setting-item>
                    <setting-item class="vertical-list-item ${wsClass}" data-direction="row" style="display: ${config.ob11.enableWs ? '' : 'none'}">
                        <setting-text>正向Websocket监听端口</setting-text>
                        <input id="wsPort" type="number" value="${config.ob11.wsPort}"/>
                    </setting-item>
                    
                    <setting-item data-direction="row" class="hostItem vertical-list-item">
                        <div>
                            <div>启用反向Websocket协议</div>
                        </div>
                        <setting-switch id="websocketReverse" ${config.ob11.enableWsReverse ? 'is-active' : ''}></setting-switch>
                    </setting-item>
                    <div class="${reverseWSClass}" style="display: ${config.ob11.enableWsReverse ? '' : 'none'}">
                        <div>
                            <button id="addWsHost" class="q-button">添加反向Websocket地址</button>
                        </div>
                        <div id="wsHostItems">
                            ${wsHostsEleStr}
                        </div>
                    </div>
                    <setting-item class="vertical-list-item" data-direction="row">
                        <setting-text>Access Token</setting-text>
                        <input id="token" type="text" placeholder="可为空" value="${config.token}"/>
                    </setting-item>
                    <setting-item data-direction="row" class="vertical-list-item">
                        <setting-item data-direction="row" class="vertical-list-item" style="width: 80%">
                            <setting-text>ffmpeg路径</setting-text>
                            <input id="ffmpegPath" class="input-text" type="text" 
                                style="width:80%;padding: 5px"
                                value="${config.ffmpeg || ''}"/>
                        </setting-item>
                        <button id="selectFFMPEG" class="q-button q-button--small q-button--secondary">选择ffmpeg</button>
                    </setting-item>
                    <button id="save" class="q-button">保存</button>
                </setting-list>
            </setting-panel>
            <setting-panel>

                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <setting-text>消息上报数据类型</setting-text>
                        <setting-text data-type="secondary">如客户端无特殊需求推荐保持默认设置,两者的详细差异可参考 <a href="javascript:LiteLoader.api.openExternal('https://github.com/botuniverse/onebot-11/tree/master/message#readme');">OneBot v11 文档</a></setting-text>
                    </div>
                    <setting-select id="messagePostFormat">
                        <setting-option data-value="array" ${config.ob11.messagePostFormat !== 'string' ? 'is-selected' : ''}>消息段</setting-option>
                        <setting-option data-value="string" ${config.ob11.messagePostFormat === 'string' ? 'is-selected' : ''}>CQ码</setting-option>
                    </setting-select>
                </setting-item>
                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <div>获取文件使用base64编码</div>
                        <div class="tips">开启后,调用/get_image、/get_record时,获取不到url时添加一个base64字段</div>
                    </div>
                    <setting-switch id="switchFileUrl" ${config.enableLocalFile2Url ? 'is-active' : ''}></setting-switch>
                </setting-item>
                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <div>debug模式</div>
                        <div class="tips">开启后上报消息添加raw字段附带原始消息</div>
                    </div>
                    <setting-switch id="debug" ${config.debug ? 'is-active' : ''}></setting-switch>
                </setting-item>
                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <div>上报自身发送消息</div>
                        <div class="tips"></div>
                    </div>
                    <setting-switch id="reportSelfMessage" ${config.reportSelfMessage ? 'is-active' : ''}></setting-switch>
                </setting-item>
                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <div>日志</div>
                        <div class="tips">目录:${window.LiteLoader.plugins.LLOneBot.path.data}</div>
                    </div>
                    <setting-switch id="log" ${config.log ? 'is-active' : ''}></setting-switch>
                </setting-item>
                <setting-item data-direction="row" class="vertical-list-item">
                    <div>
                        <div>自动删除收到的文件</div>
                        <div class="tips">
                            收到文件
                            <input id="autoDeleteMin" 
                                min="1" style="width: 50px"
                                value="${config.autoDeleteFileSecond || 60}" type="number"/>秒后自动删除
                        </div>
                    </div>
                    <setting-switch id="autoDeleteFile" ${config.autoDeleteFile ? 'is-active' : ''}></setting-switch>
                </setting-item>
            </setting-panel>
        </setting-section>
    </div>
    <style>
        setting-panel {
            padding: 10px;
        }
        .tips {
            font-size: 0.75rem;
        }
        @media (prefers-color-scheme: dark){
            .llonebot input {
                color: white;
            }
        }
    </style>
    `

  const parser = new DOMParser()
  const doc = parser.parseFromString(html, 'text/html')

  const getError = async () => {
    const llonebotError = await window.llonebot.getError()
    console.log(llonebotError)
    const llonebotErrorEle = document.getElementById('llonebotError')
    const ffmpegErrorEle = document.getElementById('ffmpegError')
    const otherErrorEle = document.getElementById('otherError')
    if (llonebotError.otherError || llonebotError.ffmpegError) {
      llonebotErrorEle.style.display = ''
    } else {
      llonebotErrorEle.style.display = 'none'
    }
    if (llonebotError.ffmpegError) {
      const errContentEle = doc.querySelector('#ffmpegError .err-content')
      // const errContent = ffmpegErrorEle.getElementsByClassName("err-content")[0];
      errContentEle.textContent = llonebotError.ffmpegError;
      (ffmpegErrorEle).style.display = ''
    } else {
      ffmpegErrorEle.style.display = ''
    }
    if (llonebotError.otherError) {
      const errContentEle = doc.querySelector('#otherError .err-content')
      errContentEle.textContent = llonebotError.otherError
      otherErrorEle.style.display = ''
    } else {
      otherErrorEle.style.display = 'none'
    }
  }

  function addHostEle (type: string, initValue: string = '') {
    let addressEle, hostItemsEle
    if (type === 'ws') {
      const addressDoc = parser.parseFromString(createWsHostEleStr(initValue), 'text/html')
      addressEle = addressDoc.querySelector('setting-item')
      hostItemsEle = document.getElementById('wsHostItems')
    } else {
      const addressDoc = parser.parseFromString(createHttpHostEleStr(initValue), 'text/html')
      addressEle = addressDoc.querySelector('setting-item')
      hostItemsEle = document.getElementById('httpHostItems')
    }

    hostItemsEle.appendChild(addressEle)
  }

  doc.getElementById('addHttpHost').addEventListener('click', () => {
    addHostEle('http')
  })
  doc.getElementById('addWsHost').addEventListener('click', () => {
    addHostEle('ws')
  })
  doc.getElementById('messagePostFormat').addEventListener('selected', (e: CustomEvent) => {
    config.ob11.messagePostFormat = e.detail && !isEmpty(e.detail.value) ? e.detail.value : 'array'
    window.llonebot.setConfig(config)
  })

  function switchClick (eleId: string, configKey: string, _config = null) {
    if (!_config) {
      _config = config
    }
    doc.getElementById(eleId)?.addEventListener('click', (e) => {
      const switchEle = e.target as HTMLInputElement
      if (_config[configKey]) {
        _config[configKey] = false
        switchEle.removeAttribute('is-active')
      } else {
        _config[configKey] = true
        switchEle.setAttribute('is-active', '')
      }
      // 妈蛋,手动操作DOM越写越麻烦,要不用vue算了
      const keyClassMap = {
        enableHttp: httpClass,
        enableHttpPost: httpPostClass,
        enableWs: wsClass,
        enableWsReverse: reverseWSClass
      }
      for (const e of document.getElementsByClassName(keyClassMap[configKey])) {
        (e as HTMLElement).style.display = _config[configKey] ? '' : 'none'
      }

      window.llonebot.setConfig(config)
    })
  }

  switchClick('http', 'enableHttp', config.ob11)
  switchClick('httpPost', 'enableHttpPost', config.ob11)
  switchClick('websocket', 'enableWs', config.ob11)
  switchClick('websocketReverse', 'enableWsReverse', config.ob11)
  switchClick('debug', 'debug')
  switchClick('switchFileUrl', 'enableLocalFile2Url')
  switchClick('reportSelfMessage', 'reportSelfMessage')
  switchClick('log', 'log')
  switchClick('autoDeleteFile', 'autoDeleteFile')

  doc.getElementById('save')?.addEventListener('click',
    () => {
      const httpPortEle: HTMLInputElement = document.getElementById('httpPort') as HTMLInputElement
      const httpHostEles: HTMLCollectionOf<HTMLInputElement> = document.getElementsByClassName('httpHost') as HTMLCollectionOf<HTMLInputElement>
      const wsPortEle: HTMLInputElement = document.getElementById('wsPort') as HTMLInputElement
      const wsHostEles: HTMLCollectionOf<HTMLInputElement> = document.getElementsByClassName('wsHost') as HTMLCollectionOf<HTMLInputElement>
      const tokenEle = document.getElementById('token') as HTMLInputElement
      const ffmpegPathEle = document.getElementById('ffmpegPath') as HTMLInputElement

      // 获取端口和host
      const httpPort = httpPortEle.value
      const httpHosts: string[] = []

      for (const hostEle of httpHostEles) {
        const value = hostEle.value.trim()
        value && httpHosts.push(value)
      }

      const wsPort = wsPortEle.value
      const token = tokenEle.value.trim()
      const wsHosts: string[] = []

      for (const hostEle of wsHostEles) {
        const value = hostEle.value.trim()
        value && wsHosts.push(value)
      }

      config.ob11.httpPort = parseInt(httpPort)
      config.ob11.httpHosts = httpHosts
      config.ob11.wsPort = parseInt(wsPort)
      config.ob11.wsHosts = wsHosts
      config.token = token
      config.ffmpeg = ffmpegPathEle.value.trim()
      window.llonebot.setConfig(config)
      setTimeout(() => {
        getError().then()
      }, 1000)
      alert('保存成功')
    })

  doc.getElementById('selectFFMPEG')?.addEventListener('click', () => {
    window.llonebot.selectFile().then(selectPath => {
      if (selectPath) {
        config.ffmpeg = (document.getElementById('ffmpegPath') as HTMLInputElement).value = selectPath
        // window.llonebot.setConfig(config);
      }
    })
  })

  // 自动保存删除文件延时时间
  const autoDeleteMinEle = doc.getElementById('autoDeleteMin') as HTMLInputElement
  let st = null
  autoDeleteMinEle.addEventListener('change', () => {
    if (st) {
      clearTimeout(st)
    }
    st = setTimeout(() => {
      console.log('auto delete file minute change')
      config.autoDeleteFileSecond = parseInt(autoDeleteMinEle.value) || 1
      window.llonebot.setConfig(config)
    }, 1000)
  })

  doc.body.childNodes.forEach(node => {
    view.appendChild(node)
  })
}

function init () {
  const hash = location.hash
  if (hash === '#/blank') {

  }
}

if (location.hash === '#/blank') {
  (window as any).navigation.addEventListener('navigatesuccess', init, { once: true })
} else {
  init()
}

export {
  onSettingWindowCreated
}