/*
 * Copyright (c) 2026 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import nativeexport from 'libnativeexport.so';
import { fileIo } from '@kit.CoreFileKit';
import Logger from './Logger';
import { PROGRESS_COMPLETE } from '../constants/CommonConstants';

const TAG = '[NativeExportUtil]';

export interface NativeWatermarkParam {
  path: string;
  relX: number;
  relY: number;
  relSize: number;
}

export class NativeExportUtil {
  static async exportVideo(
    inputPath: string,
    outputPath: string,
    watermarks: NativeWatermarkParam[],
    rotation: number,
    onProgress: (percent: number) => void,
    onCoverReady: (width: number, height: number) => void
  ): Promise<number> {
    let inputFile: fileIo.File | undefined;
    let outputFile: fileIo.File | undefined;

    try {
      inputFile = fileIo.openSync(inputPath, fileIo.OpenMode.READ_ONLY);
      outputFile = fileIo.openSync(outputPath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
      fileIo.truncateSync(outputFile.fd);

      const stat = fileIo.statSync(inputPath);
      // [Start native_wm_params]
      const wmParams: nativeexport.WatermarkParam[] = [];
      for (let i = 0; i < watermarks.length; i++) {
        wmParams.push({
          path: watermarks[i].path,
          relX: watermarks[i].relX,
          relY: watermarks[i].relY,
          relSize: watermarks[i].relSize,
        });
      }
      // [End native_wm_params]

      // [Start native_export_promise]
      return new Promise<number>((resolve) => {
        nativeexport.startExport(
          inputFile?.fd ?? -1,
          0,
          stat.size,
          outputFile?.fd ?? -1,
          wmParams,
          rotation,
          (percent: number) => {
            onProgress(percent);
          },
          (result: number) => {
            if (inputFile) {
              try {
                fileIo.closeSync(inputFile.fd);
              } catch (error) {
                Logger.error(TAG, `inputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
              }
            }
            if (outputFile) {
              try {
                fileIo.closeSync(outputFile.fd);
              } catch (error) {
                Logger.error(TAG, `outputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
              }
            }
            onProgress(PROGRESS_COMPLETE);
            onCoverReady(0, 0);
            resolve(result);
          }
        );
      });
      // [End native_export_promise]
    } catch (e) {
      Logger.error(TAG, `exportVideo failed: ${e.code}, ${e.message}`);
      if (inputFile) {
        try {
          fileIo.closeSync(inputFile.fd);
        } catch (error) {
          Logger.error(TAG, `inputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
        }
      }
      if (outputFile) {
        try {
          fileIo.closeSync(outputFile.fd);
        } catch (error) {
          Logger.error(TAG, `outputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
        }
      }
      return -1;
    }
  }

  // [Start native_cancel]
  static cancelExport(): void {
    nativeexport.cancelExport();
  }
  // [End native_cancel]
}