import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';

import '../../model/account_data.dart';
import '../../model/endpoint_data.dart';
import '../../share_intent/remote_file_ref.dart';
import '../app_progress_indicator.dart';

/// Nextcloud's `/index.php/core/preview` endpoint — returns a rasterized
/// thumbnail for any file the server has a preview provider for (images,
/// PDFs with the right backend, Office in some setups). Falls back to an
/// HTTP 404 when no preview is available, which lets [CachedNetworkImage]
/// trigger its `errorWidget`. Prefers `fileId` because the path variant
/// is unreliable on some server configurations.
String _ncPreviewUrl(RemoteFileRef remote, {int width = 1024}) {
  final host = EndpointData().nextcloud().full();
  final id = remote.fileId;
  final selector = id != null
      ? 'fileId=$id'
      : 'file=${Uri.encodeQueryComponent(remote.path)}';
  return 'https://$host/index.php/core/preview?$selector&x=$width&y=-1&a=1';
}

/// Header block for the "Vorschau nicht verfügbar" screen.
///
/// Two visual modes — kept layout-equivalent so the screen looks identical
/// whether the server already said "no preview" or the probe failed late:
///   * **No preview available** (server said no, no remoteFile, or probe
///     errored): compact "file icon + 'Vorschau nicht verfügbar' text".
///   * **Preview rendering / loaded**: mid-sized thumbnail without text.
class UnknownPreviewBlock extends StatefulWidget {
  final RemoteFileRef? remoteFile;
  const UnknownPreviewBlock({super.key, required this.remoteFile});

  @override
  State<UnknownPreviewBlock> createState() => _UnknownPreviewBlockState();
}

class _UnknownPreviewBlockState extends State<UnknownPreviewBlock> {
  static const double _previewSize = 180;
  bool _failed = false;

  Widget _compact(ThemeData theme) => Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      const Icon(Icons.insert_drive_file_outlined, size: 60),
      const SizedBox(height: 16),
      Text(
        'Vorschau nicht verfügbar',
        style: theme.textTheme.titleMedium,
        textAlign: TextAlign.center,
      ),
    ],
  );

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final remote = widget.remoteFile;
    final canProbe =
        remote != null &&
        remote.hasPreview != false &&
        remote.fileId != null &&
        !_failed;
    if (!canProbe) return _compact(theme);
    return SizedBox(
      width: _previewSize,
      height: _previewSize,
      child: CachedNetworkImage(
        httpHeaders: AccountData().authHeaders(),
        imageUrl: _ncPreviewUrl(remote, width: 360),
        fadeInDuration: Duration.zero,
        fadeOutDuration: Duration.zero,
        // Late probe failure: re-render into the compact layout so the
        // screen doesn't keep a 180×180 box around a tiny icon. Deferred
        // to the next frame because setState during build is illegal.
        errorListener: (_) {
          if (!mounted) return;
          WidgetsBinding.instance.addPostFrameCallback((_) {
            if (mounted) setState(() => _failed = true);
          });
        },
        placeholder: (_, _) =>
            const Center(child: AppProgressIndicator.large()),
        // Briefly empty while the post-frame setState swaps layouts.
        errorWidget: (_, _, _) => const SizedBox.shrink(),
        imageBuilder: (_, imageProvider) => ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: Image(
            image: imageProvider,
            fit: BoxFit.contain,
            width: _previewSize,
            height: _previewSize,
          ),
        ),
      ),
    );
  }
}
