import type {
  BaseElement,
  EditConfig,
  ElementMetadata,
} from "@/definitions/shared/base"
import type { ValidationConfig } from "@/definitions/shared/validation"

/**
 * Variants of the `file` element type. Each value here maps 1:1 to a
 * Vue file under `src/elements/file/` via the engine's registry.
 */
export type FileStyle = "upload" | "dropzone" | "asset-picker"

export interface FileElement extends BaseElement<`file.${FileStyle}`> {
  name: string
  label?: string
  /**
   * MIME-type / extension hint string. Mirrors the HTML `accept` attribute
   * and the v2 schema (e.g. "image/jpg, image/jpeg, image/png, application/pdf").
   */
  accept?: string
  /** Parsed list form — engine accepts either `accept` or `acceptedFileTypes`. */
  acceptedFileTypes?: ReadonlyArray<string>
  /** Allow selecting more than one file. */
  multiple?: boolean
  /** Maximum size in bytes for any single uploaded file. */
  maxFileSize?: number
  /** For `asset-picker`: filter the asset library to a specific category. */
  assetType?: string
  /** Validation rules (Laravel-style strings). */
  validation?: ValidationConfig
}

export const FileElementDefaults = {
  type: "file.upload",
  label: "File Upload",
  disabled: false,
  columns: 12,
  columnsSm: 12,
  columnsMd: 12,
  columnsLg: 12,
  columnsXl: 12,
} as const satisfies Partial<FileElement>

export const FileElementMetadata = {
  icon: "photo-film-music",
  displayLabel: "File Upload",
  elementCategory: "file",
  description:
    "Upload files or invoke the asset picker to select an asset from the library.",
} as const satisfies ElementMetadata

export const FileElementEditConfig = {
  label: {
    type: "input.text",
    defaultValue: "",
    label: "Label",
    columnsMd: 6,
    columns: 12,
    section: "configuration",
  },
  defaultValue: {
    type: "input.text",
    label: "Default Value",
    columnsMd: 6,
    columns: 12,
    section: "configuration",
  },
  name: {
    type: "picker.data-model",
    defaultValue: "",
    label: "Name",
    columns: 12,
    section: "advanced",
  },
  style: {
    type: "option-select.select",
    defaultValue: "upload",
    label: "Input Style",
    columns: 6,
    selectOptions: [
      { label: "Upload", value: "upload" },
      { label: "Dropzone", value: "dropzone" },
      { label: "Asset Picker", value: "asset-picker" },
    ],
    section: "layout",
  },
  accept: {
    type: "input.text",
    label:
      "Accept File Types (comma separated: 'image/jpg, image/jpeg, image/png, image/*, application/pdf')",
    columns: 12,
    section: "configuration",
  },
  multiple: {
    type: "boolean.switch",
    label: "Allow multiple files",
    columns: 6,
    section: "configuration",
  },
  maxFileSize: {
    type: "input.text",
    contentType: "integer",
    label: "Max File Size (bytes)",
    columns: 6,
    section: "configuration",
  },
  assetType: {
    type: "input.text",
    label: "Asset Type",
    columns: 12,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "==", value: "asset-picker" }],
  },
  required: {
    type: "boolean.switch",
    label: "Make item required",
    columns: 12,
    section: "configuration",
  },
  readonly: {
    type: "boolean.switch",
    label: "Make item read-only",
    columns: 12,
    section: "configuration",
  },
} as const satisfies EditConfig

export const FileStyleMetadataMap: Partial<Record<FileStyle, { displayLabel: string; description: string }>> = {
  upload: { displayLabel: "File Upload", description: "A button-triggered file upload input." },
  dropzone: { displayLabel: "Dropzone", description: "A drag-and-drop file upload area." },
  "asset-picker": { displayLabel: "Asset Picker", description: "Browse and select files from the asset library." },
}
