import { contextBridge, ipcRenderer, shell } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
import api from './api'

const applicationLoader = `
<div style="
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  margin-top: 40px;
  text-align: center;
">
  <div style="
    width: 48px;
    height: 48px;
    border: 4px solid #333333;
    border-top-color: #0071e3;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  "></div>
  <style>
    @keyframes spin {
      to { transform: rotate(360deg); }
    }
  </style>
</div>
`;

const applicationError = `
<div style="
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  height: 100vh;
  color: #ffffff;
  padding: 40px;
  text-align: center;
">
  <div style="
      flex-direction: column;
    align-items: center;
    justify-content: center;
  ">
  <div style="
    font-size: 72px;
    margin-bottom: 20px;
  ">
    <svg width="64" height="64" zoomAndPan="magnify" viewBox="0 0 384 383.999986" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="ab9f3e3410"><path d="M 134 109 L 369.46875 109 L 369.46875 381.34375 L 134 381.34375 Z M 134 109 " clip-rule="nonzero"/></clipPath><clipPath id="39bead0a6b"><path d="M 14.71875 2.59375 L 249 2.59375 L 249 222 L 14.71875 222 Z M 14.71875 2.59375 " clip-rule="nonzero"/></clipPath></defs><g clip-path="url(#ab9f3e3410)"><path fill="#ffffff" d="M 254.15625 284.453125 C 288.414062 275.191406 316.179688 260.617188 337.414062 240.769531 C 358.632812 220.917969 369.257812 195.238281 369.257812 163.691406 L 369.257812 109.996094 L 249.550781 110.222656 L 249.550781 168.148438 C 249.550781 184.847656 241.75 198.195312 226.148438 208.21875 C 210.550781 218.226562 188.175781 223.234375 159.007812 223.234375 L 134.070312 223.234375 L 134.070312 300.996094 L 206.652344 381.429688 L 344.765625 381.429688 L 254.15625 284.453125 " fill-opacity="1" fill-rule="nonzero"/></g><g clip-path="url(#39bead0a6b)"><path fill="#ffffff" d="M 248.417969 109.257812 L 248.417969 2.605469 L 14.769531 2.605469 L 14.769531 221.519531 L 132.9375 221.519531 L 132.9375 109.257812 L 248.417969 109.257812 " fill-opacity="1" fill-rule="nonzero"/></g></svg>
  </div>
  <h1 style="
    font-size: 32px;
    font-weight: 600;
    margin: 0 0 12px 0;
    letter-spacing: -0.5px;
  ">Application Error</h1>
  <p style="
    font-size: 17px;
    color: #a1a1a6;
    margin: 0 0 32px 0;
    max-width: 500px;
    line-height: 1.5;
  ">The application failed to load properly. Please wait for application repairing or reinstall application.</p>
   ${applicationLoader}  
  </div>
  <div style="
    display: flex;
    flex-direction: row;
    gap: 8px;
    justify-content: center;
    align-items: center;
    ">
      <p style="
      font-size: 13px;
      color: #5a5a5f;
    ">rosetta - powering freedom. visit about rosetta-im.com. error: boot_process_failed</p>
  </div>
</div>
`;


const exposeContext = async () => {
	let version = await ipcRenderer.invoke("get-core-version");
	let appPath = await ipcRenderer.invoke("get-app-path");
	let arch = await ipcRenderer.invoke("get-arch");
	let deviceName = await ipcRenderer.invoke("device:name");
	let deviceId = await ipcRenderer.invoke("device:id");
	let interval : any = 0;

	interval = setInterval(() => {
		/**
		 * Если после определенного таймаута приложение так и 
		 * не загрузилось, то считаем, что процесс завис,
		 * и показываем экран ошибки. Так же отправляем
		 * сигнал в main процесс, чтобы тот мог попытаться
		 * откатить обновление
		 */
		if (document.body.innerHTML.indexOf("preloadersignature") !== -1) {
			/**
			 * Если сейчас показывается прелоадер, то не считаем
			 * что обновление битое, так как само обновление еще не
			 * загрузилось в приложение
			 */
			return;
		}
		if (document.body.innerHTML.length < 100) {
			/**
			 * Приложение загружено, а прошло больше 5 секунд
			 * с момента прелоадера, значит что-то пошло не так
			 * и нужно показать экран ошибки
			 */
			document.body.innerHTML = applicationError;
			ipcRenderer.invoke("report-boot-process-failed");
		}
		clearInterval(interval);
	}, 5000);

	let downloadsPath = await ipcRenderer.invoke("get-downloads-path");
	if (process.contextIsolated) {
		try {
			contextBridge.exposeInMainWorld('electron', electronAPI)
			contextBridge.exposeInMainWorld('api', api)
			contextBridge.exposeInMainWorld('version', version);
			contextBridge.exposeInMainWorld('platform', process.platform);
			contextBridge.exposeInMainWorld('appPath', appPath);
			contextBridge.exposeInMainWorld('arch', arch);
			contextBridge.exposeInMainWorld('deviceName', deviceName);
			contextBridge.exposeInMainWorld('deviceId', deviceId);
			contextBridge.exposeInMainWorld('shell', {
				openExternal: (url: string) => {
					ipcRenderer.invoke('openExternal', url);
				},
				showItemInFolder: (fullPath: string) => {
					ipcRenderer.invoke('showItemInFolder', fullPath);
				}
			});
			contextBridge.exposeInMainWorld('downloadsPath', downloadsPath)
		} catch (error) {
			console.error(error)
		}
	} else {
		window.electron = electronAPI
		window.api = api
		window.version = version;
		window.platform = process.platform;
		window.appPath = appPath;
		window.arch = arch;
		window.shell = shell;
		window.downloadsPath = downloadsPath;
		window.deviceName = deviceName;
		window.deviceId = deviceId;
	}
}

exposeContext();