import { Check, Copy, Download, Grid3X3, Link2 } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';

import { resolveAssetReadUrl } from '../../services/assetReadUrlService';
import { isWechatMiniProgramWebViewRuntime } from '../../services/authService';
import { copyTextToClipboard } from '../../services/clipboard';
import {
  canUseWechatMiniProgramShareGrid,
  openWechatMiniProgramShareGridPage,
} from '../../services/wechatMiniProgramShareGrid';
import { useAuthUi } from '../auth/AuthUiContext';
import { ResolvedAssetImage } from '../ResolvedAssetImage';
import { downloadPublishShareCardImage } from './publishShareCardImage';
import {
  buildPublishShareCopyUrl,
  type PublishShareModalPayload,
} from './publishShareModalModel';
import { PlatformUtilityInfoModal } from './PlatformUtilityInfoModal';

type PublishShareModalProps = {
  open: boolean;
  payload: PublishShareModalPayload | null;
  onClose: () => void;
};

type ActionState = 'idle' | 'success' | 'failed';

function normalizePayloadTitle(payload: PublishShareModalPayload | null) {
  return payload?.title.trim() || '我的作品';
}

function resolvePayloadCoverImageSrc(payload: PublishShareModalPayload | null) {
  return (
    payload?.coverImageSrc?.trim() ||
    payload?.fallbackCoverImageSrc?.trim() ||
    ''
  );
}

function resolvePayloadWorkTypeLabel(payload: PublishShareModalPayload | null) {
  return payload?.workTypeLabel?.trim() || '互动作品';
}

/**
 * 发布完成后的通用分享弹窗。
 * 分享事实仍来自公开作品号与 stage；弹窗只负责把它表现成可复制、可下载的分享卡。
 */
export function PublishShareModal({
  open,
  payload,
  onClose,
}: PublishShareModalProps) {
  const platformTheme = useAuthUi()?.platformTheme ?? 'light';
  const [copyState, setCopyState] = useState<ActionState>('idle');
  const [downloadState, setDownloadState] = useState<ActionState>('idle');
  const [gridState, setGridState] = useState<ActionState>('idle');
  const resetTimerRef = useRef<number | null>(null);
  const shareCopyUrl = useMemo(
    () =>
      payload
        ? buildPublishShareCopyUrl(payload, {
            miniProgramRuntime: isWechatMiniProgramWebViewRuntime(),
          })
        : '',
    [payload],
  );
  const title = normalizePayloadTitle(payload);
  const coverImageSrc = resolvePayloadCoverImageSrc(payload);
  const workTypeLabel = resolvePayloadWorkTypeLabel(payload);
  const showMiniProgramGridButton =
    canUseWechatMiniProgramShareGrid() && Boolean(coverImageSrc);

  useEffect(
    () => () => {
      if (resetTimerRef.current !== null) {
        window.clearTimeout(resetTimerRef.current);
      }
    },
    [],
  );

  useEffect(() => {
    setCopyState('idle');
    setDownloadState('idle');
    setGridState('idle');
  }, [payload?.publicWorkCode]);

  const scheduleStateReset = () => {
    if (resetTimerRef.current !== null) {
      window.clearTimeout(resetTimerRef.current);
    }
    resetTimerRef.current = window.setTimeout(() => {
      resetTimerRef.current = null;
      setCopyState('idle');
      setDownloadState('idle');
      setGridState('idle');
    }, 1400);
  };

  const copyShareLink = () => {
    if (!shareCopyUrl) {
      return;
    }

    void copyTextToClipboard(shareCopyUrl).then((copied) => {
      setCopyState(copied ? 'success' : 'failed');
      scheduleStateReset();
    });
  };

  const resolveMiniProgramGridCover = async () => {
    if (!coverImageSrc) {
      return '';
    }

    return await resolveAssetReadUrl(coverImageSrc, {
      expireSeconds: 600,
    }).catch(() => coverImageSrc);
  };

  const downloadShareCard = () => {
    if (!payload) {
      return;
    }

    setDownloadState('idle');
    void downloadPublishShareCardImage(
      {
        ...payload,
        title,
        workTypeLabel,
        coverImageSrc,
      },
      coverImageSrc,
    )
      .then((downloaded) => {
        setDownloadState(downloaded ? 'success' : 'failed');
        scheduleStateReset();
      })
      .catch(() => {
        setDownloadState('failed');
        scheduleStateReset();
      });
  };

  const openMiniProgramGridDownload = () => {
    if (!payload || !coverImageSrc) {
      return;
    }

    setGridState('idle');
    void resolveMiniProgramGridCover()
      .then((resolvedCoverImageSrc) =>
        openWechatMiniProgramShareGridPage({
          imageUrl: resolvedCoverImageSrc,
          title,
          publicWorkCode: payload.publicWorkCode,
        }),
      )
      .then((opened) => {
        setGridState(opened ? 'success' : 'failed');
        scheduleStateReset();
      })
      .catch(() => {
        setGridState('failed');
        scheduleStateReset();
      });
  };

  return (
    <PlatformUtilityInfoModal
      open={open && Boolean(payload)}
      title="分享给朋友"
      onClose={onClose}
      platformTheme={platformTheme}
      panelClassName="rounded-[1.75rem]"
      footerClassName="border-t-0 px-4 pb-5 pt-0 sm:px-5"
      footer={
        <div
          className={`grid w-full gap-3 ${
            showMiniProgramGridButton ? 'grid-cols-1 sm:grid-cols-3' : 'grid-cols-2'
          }`}
        >
          <button
            type="button"
            onClick={copyShareLink}
            disabled={!shareCopyUrl}
            className="platform-button platform-button--primary min-h-11 justify-center gap-2 text-sm disabled:cursor-not-allowed disabled:opacity-55"
          >
            {copyState === 'success' ? (
              <Check className="h-4 w-4" />
            ) : (
              <Link2 className="h-4 w-4" />
            )}
            {copyState === 'success'
              ? '已复制'
              : copyState === 'failed'
                ? '复制失败'
                : '复制链接'}
          </button>
          <button
            type="button"
            onClick={downloadShareCard}
            disabled={!payload}
            className="platform-button platform-button--secondary min-h-11 justify-center gap-2 text-sm disabled:cursor-not-allowed disabled:opacity-55"
          >
            {downloadState === 'success' ? (
              <Check className="h-4 w-4" />
            ) : (
              <Download className="h-4 w-4" />
            )}
            {downloadState === 'success'
              ? '已下载'
              : downloadState === 'failed'
                ? '下载失败'
                : '下载卡片'}
          </button>
          {showMiniProgramGridButton ? (
            <button
              type="button"
              onClick={openMiniProgramGridDownload}
              className="platform-button platform-button--secondary min-h-11 justify-center gap-2 text-sm"
            >
              {gridState === 'success' ? (
                <Check className="h-4 w-4" />
              ) : (
                <Grid3X3 className="h-4 w-4" />
              )}
              {gridState === 'success'
                ? '已打开'
                : gridState === 'failed'
                  ? '打开失败'
                  : '九宫切图'}
            </button>
          ) : null}
        </div>
      }
    >
      <section
        className="overflow-hidden rounded-lg border border-[var(--platform-subpanel-border)] bg-white/78 shadow-[0_18px_42px_rgba(127,85,57,0.12)]"
        aria-label="分享卡片"
      >
        <div className="relative aspect-square overflow-hidden bg-[linear-gradient(135deg,#f4c38b,#e7b5b7_48%,#9bbfd1)]">
          {coverImageSrc ? (
            <ResolvedAssetImage
              src={coverImageSrc}
              alt={title}
              className="h-full w-full object-cover"
            />
          ) : (
            <div className="flex h-full w-full items-center justify-center text-6xl font-black text-white/84">
              {Array.from(title)[0] ?? '陶'}
            </div>
          )}
        </div>
        <div className="space-y-3 px-4 py-4">
          <div className="inline-flex max-w-full items-center rounded-full bg-[var(--platform-neutral-bg)] px-3 py-1 text-xs font-black text-[var(--platform-accent-text)]">
            <span className="truncate">{workTypeLabel}</span>
          </div>
          <h3 className="line-clamp-2 text-lg font-black leading-snug text-[var(--platform-text-strong)]">
            {title}
          </h3>
          <div className="flex min-w-0 items-center gap-2 text-xs font-bold text-[var(--platform-text-muted)]">
            <Copy className="h-3.5 w-3.5 shrink-0" />
            <span className="truncate">{payload?.publicWorkCode}</span>
          </div>
        </div>
      </section>
    </PlatformUtilityInfoModal>
  );
}
