export type WorkflowImageSourceType = 'resource' | 'upload' | 'url';

export type WorkflowImageValue =
  | {
      sourceType: 'url';
      url: string;
    }
  | {
      sourceType: 'resource' | 'upload';
      fileName: string;
      filePath: string;
      contentType?: string;
      size?: number;
      url?: string;
    };

export interface WorkflowImageResourceLike {
  fileSize?: number | string;
  resourceName?: string;
  resourceType?: number | string;
  resourceUrl?: string;
  suffix?: string;
}

export const WORKFLOW_IMAGE_LIMITS = {
  maxSize: 10 * 1024 * 1024,
  accept: '.png,.jpg,.jpeg,.webp,.gif,.bmp',
} as const;

const ALLOWED_MIME_TYPES = new Set([
  'image/bmp',
  'image/gif',
  'image/jpeg',
  'image/png',
  'image/webp',
]);
const ALLOWED_EXTENSIONS = new Set(['bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp']);

/**
 * 从上传结果构建单图运行值。
 */
export function buildWorkflowImageValueFromUpload(
  file: File,
  path: string,
): WorkflowImageValue {
  validateWorkflowImageFile(file);
  const filePath = String(path || '').trim();
  if (!filePath) {
    throw new Error('上传结果缺少图片路径');
  }
  return {
    sourceType: 'upload',
    fileName: file.name,
    filePath,
    contentType: file.type || undefined,
    size: file.size,
    url: filePath,
  };
}

/**
 * 从素材库对象构建单图运行值。
 */
export function buildWorkflowImageValueFromResource(
  resource: WorkflowImageResourceLike,
): WorkflowImageValue {
  const filePath = String(resource?.resourceUrl || '').trim();
  if (!filePath) {
    throw new Error('图片素材缺少 resourceUrl');
  }
  if (
    resource.resourceType !== undefined &&
    Number(resource.resourceType) !== 0
  ) {
    throw new Error('请选择图片素材');
  }
  const suffix = String(resource?.suffix || '').trim().toLowerCase();
  if (suffix && !ALLOWED_EXTENSIONS.has(suffix)) {
    throw new Error('仅支持 PNG、JPEG、WebP、GIF、BMP 图片');
  }
  const size = toNumber(resource?.fileSize);
  validateWorkflowImageSize(size);
  const resourceName = String(resource?.resourceName || '').trim();
  const fallbackName = filePath.split('/').pop()?.split('?')[0] || 'image';
  return {
    sourceType: 'resource',
    fileName:
      resourceName && suffix
        ? `${resourceName}.${suffix}`
        : resourceName || fallbackName,
    filePath,
    contentType: suffixToMimeType(suffix),
    size,
    url: filePath,
  };
}

/**
 * 从 HTTP/HTTPS URL 构建图片运行值。
 */
export function buildWorkflowImageValueFromUrl(url: string): WorkflowImageValue {
  const normalized = String(url || '').trim();
  let parsed: URL;
  try {
    parsed = new URL(normalized);
  } catch {
    throw new Error('请输入有效的图片 URL');
  }
  if (!['http:', 'https:'].includes(parsed.protocol)) {
    throw new Error('图片 URL 仅支持 HTTP/HTTPS');
  }
  return {
    sourceType: 'url',
    url: normalized,
  };
}

/**
 * 归一化新旧工作流图片值。
 */
export function normalizeWorkflowImageValue(
  value: unknown,
): WorkflowImageValue | undefined {
  if (typeof value === 'string' && value.trim()) {
    try {
      return buildWorkflowImageValueFromUrl(value);
    } catch {
      return undefined;
    }
  }
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return undefined;
  }
  const candidate = value as Record<string, unknown>;
  const filePath = String(candidate.filePath || '').trim();
  const sourceType = String(
    candidate.sourceType || (filePath ? 'upload' : 'url'),
  ) as WorkflowImageSourceType;
  if (sourceType === 'url') {
    try {
      return buildWorkflowImageValueFromUrl(String(candidate.url || ''));
    } catch {
      return undefined;
    }
  }
  if (!['resource', 'upload'].includes(sourceType)) {
    return undefined;
  }
  const fileName = String(candidate.fileName || '').trim();
  if (!fileName || !filePath) {
    return undefined;
  }
  const size = toNumber(candidate.size as number | string | undefined);
  try {
    validateWorkflowImageSize(size);
  } catch {
    return undefined;
  }
  return {
    sourceType,
    fileName,
    filePath,
    contentType: String(candidate.contentType || '').trim() || undefined,
    size,
    url: String(candidate.url || '').trim() || undefined,
  };
}

/**
 * 判断值中是否存在可提交的图片。
 */
export function hasWorkflowImageValue(value: unknown): boolean {
  return normalizeWorkflowImageValue(value) !== undefined;
}

/**
 * 获取缩略图 URL。
 */
export function getWorkflowImagePreviewUrl(value: unknown): string {
  const image = normalizeWorkflowImageValue(value);
  return image?.sourceType === 'url'
    ? image.url
    : image?.url || image?.filePath || '';
}

/**
 * 校验本地图片格式和大小。
 */
export function validateWorkflowImageFile(file: File) {
  const extension = file.name.split('.').pop()?.toLowerCase() || '';
  if (
    !ALLOWED_MIME_TYPES.has(file.type.toLowerCase()) &&
    !ALLOWED_EXTENSIONS.has(extension)
  ) {
    throw new Error('仅支持 PNG、JPEG、WebP、GIF、BMP 图片');
  }
  validateWorkflowImageSize(file.size);
}

/**
 * 格式化图片大小。
 */
export function formatWorkflowImageSize(size?: number): string {
  if (!size || size <= 0 || Number.isNaN(size)) {
    return '';
  }
  if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(1)} KB`;
  }
  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
}

function validateWorkflowImageSize(size?: number) {
  if (size !== undefined && size > WORKFLOW_IMAGE_LIMITS.maxSize) {
    throw new Error('单张图片不能超过 10 MiB');
  }
}

function suffixToMimeType(suffix: string): string | undefined {
  if (!suffix) {
    return undefined;
  }
  return suffix === 'jpg' || suffix === 'jpeg'
    ? 'image/jpeg'
    : `image/${suffix}`;
}

function toNumber(value?: number | string): number | undefined {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value;
  }
  if (typeof value === 'string' && value.trim()) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : undefined;
  }
  return undefined;
}
