import {
  History,
  ImagePlus,
  Loader2,
  Sparkles,
  Trash2,
  X,
} from 'lucide-react';
import { type ReactNode, useEffect, useState } from 'react';

import { ResolvedAssetImage } from '../ResolvedAssetImage';

export type CreativeImageInputReferenceImage = {
  id: string;
  label: string;
  imageSrc: string;
};

export type CreativeImageInputPanelLabels = {
  imageField: string;
  uploadImage: string;
  replaceImage: string;
  emptyImageHint: string;
  removeImage: string;
  removeImageConfirmTitle: string;
  removeImageConfirmBody: string;
  promptReferenceUpload: string;
  promptReferencePreviewAlt: string;
  closePromptReferencePreview: string;
  history?: string;
};

export type CreativeImageInputPanelProps = {
  className?: string;
  disabled?: boolean;
  isSubmitting?: boolean;
  mainImageMode?: 'edit' | 'preview';
  canRemoveMainImage?: boolean;
  canToggleAiRedraw?: boolean;
  uploadedImageSrc: string;
  uploadedImageAlt: string;
  uploadedImageRefreshKey?: string | number | null;
  mainImageMeta?: ReactNode;
  mainImageInputId: string;
  mainImageAccept?: string;
  promptTextareaId: string;
  prompt: string;
  promptLabel: string;
  promptAriaLabel?: string;
  promptRows?: number;
  aiRedraw: boolean;
  promptReferenceImages: CreativeImageInputReferenceImage[];
  promptReferenceLimit?: number;
  imageModelPicker?: ReactNode;
  error?: string | null;
  inputError?: string | null;
  submitLabel: string;
  submitCostLabel?: string | null;
  submitDisabled: boolean;
  labels: CreativeImageInputPanelLabels;
  onMainImageFileSelect: (file: File) => void;
  onMainImageRemove: () => void;
  onAiRedrawChange: (enabled: boolean) => void;
  onPromptChange: (value: string) => void;
  onPromptReferenceFilesSelect?: (files: File[]) => void;
  onPromptReferenceRemove?: (referenceId: string) => void;
  onHistoryClick?: () => void;
  onSubmit: () => void;
};

const DEFAULT_IMAGE_ACCEPT = 'image/png,image/jpeg,image/webp';
const DEFAULT_PROMPT_REFERENCE_LIMIT = 5;

export function CreativeImageInputPanel({
  className = '',
  disabled = false,
  isSubmitting = false,
  mainImageMode = 'edit',
  canRemoveMainImage = true,
  canToggleAiRedraw = true,
  uploadedImageSrc,
  uploadedImageAlt,
  uploadedImageRefreshKey = null,
  mainImageMeta = null,
  mainImageInputId,
  mainImageAccept = DEFAULT_IMAGE_ACCEPT,
  promptTextareaId,
  prompt,
  promptLabel,
  promptAriaLabel,
  promptRows = 2,
  aiRedraw,
  promptReferenceImages,
  promptReferenceLimit = DEFAULT_PROMPT_REFERENCE_LIMIT,
  imageModelPicker = null,
  error = null,
  inputError = null,
  submitLabel,
  submitCostLabel = null,
  submitDisabled,
  labels,
  onMainImageFileSelect,
  onMainImageRemove,
  onAiRedrawChange,
  onPromptChange,
  onPromptReferenceFilesSelect,
  onPromptReferenceRemove,
  onHistoryClick,
  onSubmit,
}: CreativeImageInputPanelProps) {
  const [previewReferenceImage, setPreviewReferenceImage] =
    useState<CreativeImageInputReferenceImage | null>(null);
  const [isRemoveImageConfirmOpen, setIsRemoveImageConfirmOpen] =
    useState(false);
  const showPrompt = mainImageMode === 'preview' || !uploadedImageSrc || aiRedraw;
  const promptReferenceUploadDisabled =
    disabled || promptReferenceImages.length >= promptReferenceLimit;
  const canEditMainImage = mainImageMode === 'edit';

  useEffect(() => {
    if (uploadedImageSrc) {
      setPreviewReferenceImage(null);
    }
  }, [uploadedImageSrc]);

  useEffect(() => {
    if (
      previewReferenceImage &&
      !promptReferenceImages.some(
        (reference) => reference.id === previewReferenceImage.id,
      )
    ) {
      setPreviewReferenceImage(null);
    }
  }, [previewReferenceImage, promptReferenceImages]);

  return (
    <div
      className={`creative-image-input-panel flex min-h-0 flex-1 flex-col ${className}`}
    >
      <div className="creative-image-input-panel__body puzzle-creation-form-body flex min-h-0 flex-1 flex-col overflow-hidden pr-0 lg:overflow-y-auto lg:pr-1">
        <section className="creative-image-input-panel__section puzzle-creation-form-section flex min-h-0 flex-1 flex-col overflow-hidden lg:overflow-visible">
          <div
            className={`creative-image-input-panel__grid puzzle-creation-form-grid min-h-0 flex-1 gap-2.5 sm:gap-4 ${
              showPrompt
                ? 'flex flex-col lg:grid lg:grid-cols-[minmax(15rem,0.9fr)_minmax(0,1.15fr)]'
                : 'flex flex-col lg:grid lg:grid-cols-1'
            }`}
          >
            <div
              className={`creative-image-input-panel__image-field puzzle-image-field flex min-h-0 min-w-0 flex-1 flex-col ${
                disabled ? 'opacity-55' : ''
              }`}
            >
              <div className="mb-2 shrink-0 text-sm font-black text-[var(--platform-text-strong)]">
                {labels.imageField}
              </div>
              <div className="creative-image-input-panel__image-frame puzzle-image-card-frame flex min-h-0 flex-1 items-center justify-center">
                <div className="creative-image-input-panel__image-card puzzle-image-upload-card relative aspect-square h-full max-h-full max-w-full overflow-hidden rounded-[1.25rem] border border-[var(--platform-subpanel-border)] bg-white/90 shadow-[0_12px_28px_rgba(15,23,42,0.08)] transition lg:h-auto lg:w-full">
                  {canEditMainImage ? (
                    <>
                      <input
                        id={mainImageInputId}
                        type="file"
                        accept={mainImageAccept}
                        disabled={disabled}
                        aria-label={labels.uploadImage}
                        onChange={(event) => {
                          const file = event.currentTarget.files?.[0] ?? null;
                          event.currentTarget.value = '';
                          if (file) {
                            onMainImageFileSelect(file);
                          }
                        }}
                        className="sr-only"
                      />
                      <label
                        htmlFor={mainImageInputId}
                        className={`absolute inset-0 z-0 cursor-pointer ${disabled ? 'cursor-not-allowed' : ''}`}
                        title={
                          uploadedImageSrc ? labels.replaceImage : labels.uploadImage
                        }
                      >
                        <span className="sr-only">
                          {uploadedImageSrc ? labels.replaceImage : labels.uploadImage}
                        </span>
                      </label>
                    </>
                  ) : null}
                  {uploadedImageSrc ? (
                    <ResolvedAssetImage
                      src={uploadedImageSrc}
                      refreshKey={uploadedImageRefreshKey}
                      alt={uploadedImageAlt}
                      className="pointer-events-none absolute inset-0 h-full w-full object-cover"
                    />
                  ) : (
                    <span className="pointer-events-none flex h-full items-center justify-center bg-[radial-gradient(circle_at_50%_28%,rgba(255,255,255,0.9),transparent_38%),linear-gradient(135deg,rgba(255,255,255,0.96),rgba(255,241,229,0.86))]">
                      <span className="flex h-14 w-14 items-center justify-center rounded-full border border-[var(--platform-subpanel-border)] bg-white/92 text-[var(--platform-text-strong)] shadow-sm sm:h-20 sm:w-20">
                        <ImagePlus className="h-6 w-6 sm:h-8 sm:w-8" />
                      </span>
                    </span>
                  )}
                  <div className="pointer-events-none absolute inset-0 z-[1] bg-[linear-gradient(180deg,rgba(255,255,255,0.12)_0%,rgba(255,255,255,0.04)_42%,rgba(255,255,255,0.18)_100%)]" />
                  {canEditMainImage && onHistoryClick ? (
                    <button
                      type="button"
                      disabled={disabled}
                      onClick={onHistoryClick}
                      className={`absolute right-3 top-3 z-10 inline-flex items-center gap-1.5 rounded-full border border-white/80 bg-white/94 px-3 py-2 text-[11px] font-black text-[var(--platform-text-strong)] shadow-sm backdrop-blur transition hover:text-[var(--platform-accent)] ${
                        disabled ? 'cursor-not-allowed opacity-55' : ''
                      }`}
                      aria-label={labels.history ?? '选择历史图片'}
                      title={labels.history ?? '选择历史图片'}
                    >
                      <History className="h-3.5 w-3.5" />
                      <span>历史</span>
                    </button>
                  ) : null}
                  {canEditMainImage && uploadedImageSrc && canToggleAiRedraw ? (
                    <label className="absolute bottom-3 left-3 z-10 inline-flex cursor-pointer items-center gap-2 rounded-full border border-white/80 bg-white/94 px-3 py-2 text-xs font-black text-[var(--platform-text-strong)] shadow-sm backdrop-blur">
                      <span>AI重绘</span>
                      <input
                        role="switch"
                        type="checkbox"
                        checked={aiRedraw}
                        disabled={disabled}
                        onChange={(event) => onAiRedrawChange(event.target.checked)}
                        className="sr-only"
                        aria-label="AI重绘"
                      />
                      <span
                        aria-hidden="true"
                        className={`relative h-5 w-9 rounded-full transition ${
                          aiRedraw ? 'bg-[var(--platform-accent)]' : 'bg-zinc-300'
                        }`}
                      >
                        <span
                          className={`absolute top-0.5 h-4 w-4 rounded-full bg-white shadow-sm transition ${
                            aiRedraw ? 'left-[1.125rem]' : 'left-0.5'
                          }`}
                        />
                      </span>
                    </label>
                  ) : null}
                  {canEditMainImage && uploadedImageSrc && canRemoveMainImage ? (
                    <button
                      type="button"
                      disabled={disabled}
                      onClick={() => setIsRemoveImageConfirmOpen(true)}
                      className="absolute left-3 top-3 z-10 inline-flex h-10 w-10 items-center justify-center rounded-full border border-white/80 bg-white/94 text-[var(--platform-text-strong)] shadow-sm backdrop-blur transition hover:text-[var(--platform-accent)] disabled:cursor-not-allowed disabled:opacity-55"
                      aria-label={labels.removeImage}
                      title={labels.removeImage}
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  ) : canEditMainImage && !uploadedImageSrc ? (
                    <label
                      htmlFor={mainImageInputId}
                      className={`absolute bottom-9 left-1/2 z-10 -translate-x-1/2 whitespace-nowrap text-center text-sm font-black text-[var(--platform-text-strong)] drop-shadow-[0_1px_0_rgba(255,255,255,0.82)] transition hover:text-[var(--platform-accent)] sm:bottom-10 ${
                        disabled
                          ? 'cursor-not-allowed opacity-55'
                          : 'cursor-pointer'
                      }`}
                    >
                      {labels.emptyImageHint}
                    </label>
                  ) : null}
                </div>
              </div>
              {mainImageMeta ? <div className="mt-3 shrink-0">{mainImageMeta}</div> : null}
            </div>

            {showPrompt ? (
              <div className="block shrink-0 lg:min-h-0">
                <label
                  htmlFor={promptTextareaId}
                  className="mb-2 block text-sm font-black text-[var(--platform-text-strong)]"
                >
                  {promptLabel}
                </label>
                <div className="relative">
                  <textarea
                    id={promptTextareaId}
                    value={prompt}
                    disabled={disabled}
                    rows={promptRows}
                    placeholder=""
                    onChange={(event) => onPromptChange(event.target.value)}
                    className="h-[6rem] min-h-[6rem] w-full resize-none rounded-[1.15rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 pb-14 text-base leading-6 text-[var(--platform-text-strong)] outline-none placeholder:text-zinc-400 sm:h-[7.5rem] sm:min-h-[7.5rem] lg:h-[9.25rem] lg:min-h-[9.25rem]"
                    aria-label={promptAriaLabel ?? promptLabel}
                  />
                  {imageModelPicker}
                  {!uploadedImageSrc && onPromptReferenceFilesSelect ? (
                    <label
                      className={`absolute bottom-3 right-3 z-10 inline-flex h-8 w-8 items-center justify-center rounded-full border border-[var(--platform-subpanel-border)] bg-white/96 text-[var(--platform-text-strong)] shadow-sm transition hover:bg-[var(--platform-subpanel-fill)] hover:text-[var(--platform-accent)] ${
                        promptReferenceUploadDisabled
                          ? 'cursor-not-allowed opacity-55'
                          : 'cursor-pointer'
                      }`}
                      aria-label={labels.promptReferenceUpload}
                      title={labels.promptReferenceUpload}
                    >
                      <ImagePlus className="h-4 w-4" />
                      <input
                        type="file"
                        accept={mainImageAccept}
                        multiple
                        aria-label={labels.promptReferenceUpload}
                        disabled={promptReferenceUploadDisabled}
                        onChange={(event) => {
                          const files = Array.from(event.currentTarget.files ?? []);
                          event.currentTarget.value = '';
                          if (files.length > 0) {
                            onPromptReferenceFilesSelect(files);
                          }
                        }}
                        className="sr-only"
                      />
                    </label>
                  ) : null}
                </div>
                {!uploadedImageSrc && promptReferenceImages.length > 0 ? (
                  <div className="mt-2 flex flex-wrap gap-2">
                    {promptReferenceImages.map((reference) => (
                      <div
                        key={reference.id}
                        className="relative h-12 w-12 overflow-hidden rounded-[0.75rem] border border-[var(--platform-subpanel-border)] bg-white/90 shadow-sm"
                      >
                        <button
                          type="button"
                          disabled={disabled}
                          onClick={() => setPreviewReferenceImage(reference)}
                          className="block h-full w-full"
                          aria-label={`预览参考图 ${reference.label}`}
                          title={reference.label}
                        >
                          <ResolvedAssetImage
                            src={reference.imageSrc}
                            alt=""
                            aria-hidden="true"
                            className="h-full w-full object-cover"
                          />
                        </button>
                        {onPromptReferenceRemove ? (
                          <button
                            type="button"
                            disabled={disabled}
                            onClick={() => onPromptReferenceRemove(reference.id)}
                            className="absolute right-0.5 top-0.5 inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/94 text-[var(--platform-text-strong)] shadow-sm transition hover:text-[var(--platform-accent)] disabled:opacity-55"
                            aria-label={`移除参考图 ${reference.label}`}
                            title="移除参考图"
                          >
                            <X className="h-3 w-3" />
                          </button>
                        ) : null}
                      </div>
                    ))}
                  </div>
                ) : null}
              </div>
            ) : null}
          </div>

          <div className="mt-2 shrink-0 space-y-3">
            {inputError ? (
              <div className="platform-banner platform-banner--danger rounded-2xl text-sm leading-6">
                {inputError}
              </div>
            ) : null}
            {error ? (
              <div className="platform-banner platform-banner--danger rounded-2xl text-sm leading-6">
                {error}
              </div>
            ) : null}
          </div>
        </section>
      </div>

      <div className="mt-2 flex shrink-0 justify-center pb-[max(0.25rem,env(safe-area-inset-bottom))] sm:mt-3">
        <button
          type="button"
          disabled={disabled || submitDisabled}
          onClick={onSubmit}
          className={`platform-button platform-button--primary min-h-10 px-4 py-2 text-sm sm:min-h-11 sm:px-5 ${
            submitDisabled ? 'cursor-not-allowed opacity-55' : ''
          }`}
        >
          <span className="inline-flex flex-wrap items-center justify-center gap-1.5 sm:gap-2">
            {isSubmitting ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
            <Sparkles className="h-4 w-4" />
            <span>{submitLabel}</span>
            {submitCostLabel ? (
              <span className="rounded-full bg-white/24 px-2 py-0.5 text-[11px] font-bold">
                {submitCostLabel}
              </span>
            ) : null}
          </span>
        </button>
      </div>

      {previewReferenceImage ? (
        <div
          className="platform-modal-backdrop fixed inset-0 z-[80] flex items-center justify-center px-4 py-6"
          onClick={() => setPreviewReferenceImage(null)}
        >
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="creative-image-reference-preview-title"
            className="platform-modal-shell platform-remap-surface w-full max-w-2xl rounded-[1.35rem] p-3 shadow-[0_24px_70px_rgba(15,23,42,0.22)]"
            onClick={(event) => event.stopPropagation()}
          >
            <div className="mb-3 flex items-center justify-between gap-3 px-1">
              <div
                id="creative-image-reference-preview-title"
                className="min-w-0 truncate text-sm font-black text-[var(--platform-text-strong)]"
              >
                {previewReferenceImage.label}
              </div>
              <button
                type="button"
                aria-label={labels.closePromptReferencePreview}
                onClick={() => setPreviewReferenceImage(null)}
                className="platform-profile-icon-button flex h-8 w-8 shrink-0 items-center justify-center rounded-full"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
            <div className="max-h-[72vh] overflow-hidden rounded-[1rem] bg-black/5">
              <ResolvedAssetImage
                src={previewReferenceImage.imageSrc}
                alt={labels.promptReferencePreviewAlt}
                className="h-full max-h-[72vh] w-full object-contain"
              />
            </div>
          </div>
        </div>
      ) : null}

      {isRemoveImageConfirmOpen ? (
        <div className="platform-modal-backdrop fixed inset-0 z-[80] flex items-center justify-center px-4 py-6">
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="creative-image-remove-confirm-title"
            className="platform-modal-shell platform-remap-surface w-full max-w-xs rounded-[1.35rem] p-5 shadow-[0_24px_70px_rgba(15,23,42,0.22)]"
          >
            <div
              id="creative-image-remove-confirm-title"
              className="text-base font-black text-[var(--platform-text-strong)]"
            >
              {labels.removeImageConfirmTitle}
            </div>
            <div className="mt-2 text-sm leading-6 text-[var(--platform-text-base)]">
              {labels.removeImageConfirmBody}
            </div>
            <div className="mt-5 grid grid-cols-2 gap-3">
              <button
                type="button"
                onClick={() => setIsRemoveImageConfirmOpen(false)}
                className="platform-button platform-button--secondary justify-center"
              >
                取消
              </button>
              <button
                type="button"
                onClick={() => {
                  onMainImageRemove();
                  setIsRemoveImageConfirmOpen(false);
                }}
                className="platform-button platform-button--primary justify-center"
              >
                移除
              </button>
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}

export default CreativeImageInputPanel;
