import {
  ImageResult,
  PlatformService,
  PlatformCapabilities,
} from "../PlatformService";
import { logger } from "../../utils/logger";

/**
 * Platform service implementation for web browser platform.
 * Implements the PlatformService interface with web-specific functionality.
 *
 * @remarks
 * This service provides web-based implementations for:
 * - Image capture using the browser's file input
 * - Image selection from local filesystem
 * - Image processing and conversion
 *
 * Note: File system operations are not available in the web platform
 * due to browser security restrictions. These methods throw appropriate errors.
 */
export class WebPlatformService implements PlatformService {
  /**
   * Gets the capabilities of the web platform
   * @returns Platform capabilities object
   */
  getCapabilities(): PlatformCapabilities {
    return {
      hasFileSystem: false,
      hasCamera: true, // Through file input with capture
      isMobile: /iPhone|iPad|iPod|Android/i.test(navigator.userAgent),
      isIOS: /iPad|iPhone|iPod/.test(navigator.userAgent),
      hasFileDownload: true,
      needsFileHandlingInstructions: false,
    };
  }

  /**
   * Not supported in web platform.
   * @param _path - Unused path parameter
   * @throws Error indicating file system access is not available
   */
  async readFile(_path: string): Promise<string> {
    throw new Error("File system access not available in web platform");
  }

  /**
   * Not supported in web platform.
   * @param _path - Unused path parameter
   * @param _content - Unused content parameter
   * @throws Error indicating file system access is not available
   */
  async writeFile(_path: string, _content: string): Promise<void> {
    throw new Error("File system access not available in web platform");
  }

  /**
   * Not supported in web platform.
   * @param _path - Unused path parameter
   * @throws Error indicating file system access is not available
   */
  async deleteFile(_path: string): Promise<void> {
    throw new Error("File system access not available in web platform");
  }

  /**
   * Not supported in web platform.
   * @param _directory - Unused directory parameter
   * @throws Error indicating file system access is not available
   */
  async listFiles(_directory: string): Promise<string[]> {
    throw new Error("File system access not available in web platform");
  }

  /**
   * Opens a file input dialog configured for camera capture.
   * Creates a temporary file input element to access the device camera.
   *
   * @returns Promise resolving to the captured image data
   * @throws Error if image capture fails or no image is selected
   *
   * @remarks
   * Uses the 'capture' attribute to prefer the device camera.
   * Falls back to file selection if camera is not available.
   * Processes the captured image to ensure consistent format.
   */
  async takePicture(): Promise<ImageResult> {
    return new Promise((resolve, reject) => {
      const input = document.createElement("input");
      input.type = "file";
      input.accept = "image/*";
      input.capture = "environment";

      input.onchange = async (e) => {
        const file = (e.target as HTMLInputElement).files?.[0];
        if (file) {
          try {
            const blob = await this.processImageFile(file);
            resolve({
              blob,
              fileName: file.name || "photo.jpg",
            });
          } catch (error) {
            logger.error("Error processing camera image:", error);
            reject(new Error("Failed to process camera image"));
          }
        } else {
          reject(new Error("No image captured"));
        }
      };

      input.click();
    });
  }

  /**
   * Opens a file input dialog for selecting an image file.
   * Creates a temporary file input element to access local files.
   *
   * @returns Promise resolving to the selected image data
   * @throws Error if image processing fails or no image is selected
   *
   * @remarks
   * Allows selection of any image file type.
   * Processes the selected image to ensure consistent format.
   */
  async pickImage(): Promise<ImageResult> {
    return new Promise((resolve, reject) => {
      const input = document.createElement("input");
      input.type = "file";
      input.accept = "image/*";

      input.onchange = async (e) => {
        const file = (e.target as HTMLInputElement).files?.[0];
        if (file) {
          try {
            const blob = await this.processImageFile(file);
            resolve({
              blob,
              fileName: file.name || "photo.jpg",
            });
          } catch (error) {
            logger.error("Error processing picked image:", error);
            reject(new Error("Failed to process picked image"));
          }
        } else {
          reject(new Error("No image selected"));
        }
      };

      input.click();
    });
  }

  /**
   * Processes an image file to ensure consistent format.
   * Converts the file to a data URL and then to a Blob.
   *
   * @param file - The image File object to process
   * @returns Promise resolving to processed image Blob
   * @throws Error if file reading or conversion fails
   *
   * @remarks
   * This method ensures consistent image format across different
   * input sources by converting through data URL to Blob.
   */
  private async processImageFile(file: File): Promise<Blob> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (event) => {
        const dataUrl = event.target?.result as string;
        // Convert to blob to ensure consistent format
        fetch(dataUrl)
          .then((res) => res.blob())
          .then((blob) => resolve(blob))
          .catch((error) => {
            logger.error("Error converting data URL to blob:", error);
            reject(error);
          });
      };
      reader.onerror = (error) => {
        logger.error("Error reading file:", error);
        reject(error);
      };
      reader.readAsDataURL(file);
    });
  }

  /**
   * Checks if running on Capacitor platform.
   * @returns false, as this is not Capacitor
   */
  isCapacitor(): boolean {
    return false;
  }

  /**
   * Checks if running on Electron platform.
   * @returns false, as this is not Electron
   */
  isElectron(): boolean {
    return false;
  }

  /**
   * Checks if running on PyWebView platform.
   * @returns false, as this is not PyWebView
   */
  isPyWebView(): boolean {
    return false;
  }

  /**
   * Checks if running on web platform.
   * @returns true, as this is the web implementation
   */
  isWeb(): boolean {
    return true;
  }

  /**
   * Handles deep link URLs in the web platform.
   * Deep links are handled through URL parameters in the web environment.
   *
   * @param _url - The deep link URL to handle (unused in web implementation)
   * @returns Promise that resolves immediately as web handles URLs naturally
   */
  async handleDeepLink(_url: string): Promise<void> {
    // Web platform can handle deep links through URL parameters
    return Promise.resolve();
  }
}
