import * as RadixDialog from '@radix-ui/react-dialog';
import classNames from 'classnames';
import { motion, type Transition, type Variants } from 'framer-motion';
import { memo } from 'react';
import { useChatUsage } from '~/lib/hooks/useChatUsage';
import { DialogDescription, DialogTitle } from '../../ui/Dialog';
import { IconButton } from '../../ui/IconButton';
import { ChatUsageVisualization } from './ChatUsageVisualization';

const transition: Transition = {
  duration: 0.15,
  ease: [0.16, 1, 0.3, 1], // cubicBezier(.16,1,.3,1)
};

const backdropVariants: Variants = {
  closed: {
    opacity: 0,
    transition,
  },
  open: {
    opacity: 1,
    transition,
  },
};

const dialogVariants: Variants = {
  closed: {
    x: '-50%',
    y: '-40%',
    scale: 0.96,
    opacity: 0,
    transition,
  },
  open: {
    x: '-50%',
    y: '-50%',
    scale: 1,
    opacity: 1,
    transition,
  },
};

interface ChatUsageDialogProps {
  isOpen: boolean;
  onClose: () => void;
}

export const ChatUsageDialog = memo(({ isOpen, onClose }: ChatUsageDialogProps) => {
  const { usageStats, isLoading, refreshUsageStats } = useChatUsage();

  const formatNumber = (num: number | null) => {
    if (num === null) {
      return '0';
    }
    return num.toLocaleString();
  };

  const formatLargeNumber = (num: number | null) => {
    if (num === null) {
      return '0';
    }
    if (num < 1000) {
      return num.toString();
    }
    if (num < 1000000) {
      return `${(num / 1000).toFixed(1)}K`;
    }
    return `${(num / 1000000).toFixed(1)}M`;
  };

  // 计算成功率
  const successRate = () => {
    if (!usageStats) {
      return 0;
    }

    const successCount = usageStats.byStatus.find((s) => s.status === 'SUCCESS')?._count || 0;
    const totalCount = usageStats.total._count;

    return totalCount > 0 ? (successCount / totalCount) * 100 : 0;
  };

  // 计算平均 token 消耗
  const avgTokenPerRequest = () => {
    if (!usageStats || usageStats.total._count === 0) {
      return 0;
    }
    return (usageStats.total._sum.totalTokens || 0) / usageStats.total._count;
  };

  const cardClasses = classNames(
    'p-4 rounded-lg shadow-sm',
    'bg-upage-elements-bg-depth-1',
    'border border-upage-elements-borderColor',
  );

  return (
    <RadixDialog.Root open={isOpen} onOpenChange={onClose}>
      <RadixDialog.Portal>
        <RadixDialog.Overlay asChild>
          <motion.div
            className={classNames('fixed inset-0 z-[9999] bg-black/70 dark:bg-black/80 backdrop-blur-sm')}
            initial="closed"
            animate="open"
            exit="closed"
            variants={backdropVariants}
          />
        </RadixDialog.Overlay>

        <RadixDialog.Content asChild>
          <motion.div
            className={classNames(
              'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white dark:bg-gray-950 rounded-lg shadow-xl border border-upage-elements-borderColor z-[9999] w-[95vw] max-w-[1000px] max-h-[85vh] flex flex-col',
            )}
            initial="closed"
            animate="open"
            exit="closed"
            variants={dialogVariants}
          >
            <DialogDescription className="sr-only">
              用于展示 API 使用情况统计数据，包括请求次数、Token 用量及成功率等信息。
            </DialogDescription>
            <div className="flex items-center justify-between px-6 py-4 border-b border-upage-elements-borderColor">
              <DialogTitle>API 使用统计</DialogTitle>
              <div className="flex items-center gap-2">
                <IconButton
                  icon={isLoading ? 'i-ph:spinner-gap-bold animate-spin' : 'i-ph:arrows-clockwise'}
                  onClick={refreshUsageStats}
                  disabled={isLoading}
                  className={classNames('text-upage-elements-textTertiary hover:text-upage-elements-textSecondary', {
                    'opacity-50 cursor-not-allowed': isLoading,
                  })}
                  aria-label="刷新统计数据"
                  title="刷新统计数据"
                />
                <RadixDialog.Close asChild onClick={onClose}>
                  <IconButton
                    icon="i-ph:x"
                    className="text-upage-elements-textTertiary hover:text-upage-elements-textSecondary"
                  />
                </RadixDialog.Close>
              </div>
            </div>

            <div className="flex-1 overflow-auto relative">
              {isLoading && (
                <div className="absolute inset-0 z-10 flex items-center justify-center bg-white/70 dark:bg-gray-950/70 backdrop-blur-sm">
                  <div className="flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-white/90 dark:bg-gray-900/90 shadow-sm">
                    <div className="i-ph:spinner-gap-bold animate-spin size-5 text-upage-elements-textTertiary" />
                    <span className="text-upage-elements-textSecondary font-medium">数据刷新中...</span>
                  </div>
                </div>
              )}

              {!usageStats ? (
                <div className="flex-1 overflow-auto text-center py-12">
                  <div className="i-ph:chart-line-duotone size-12 mx-auto mb-4 text-upage-elements-textTertiary opacity-80" />
                  <h3 className="text-lg font-medium text-upage-elements-textPrimary mb-2">暂无数据</h3>
                  <p className="text-upage-elements-textSecondary">还没有使用记录，开始使用 AI 功能来生成数据统计。</p>
                </div>
              ) : (
                <div className="flex-1 overflow-auto p-6">
                  <div className="space-y-8">
                    <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
                      <div className={cardClasses}>
                        <div className="text-sm text-upage-elements-textSecondary mb-1">总请求次数</div>
                        <div className="text-2xl font-bold text-upage-elements-textPrimary flex items-center">
                          <span className="i-ph:chat-dots-duotone size-6 text-purple-500 dark:text-purple-400 mr-2" />
                          {formatNumber(usageStats.total._count)}
                        </div>
                      </div>

                      <div className={cardClasses}>
                        <div className="text-sm text-upage-elements-textSecondary mb-1">总 Token 用量</div>
                        <div className="text-2xl font-bold text-upage-elements-textPrimary flex items-center">
                          <span className="i-ph:hash-duotone size-6 text-green-500 dark:text-green-400 mr-2" />
                          {formatLargeNumber(usageStats.total._sum.totalTokens)}
                        </div>
                      </div>

                      <div className={cardClasses}>
                        <div className="text-sm text-upage-elements-textSecondary mb-1">输入 Token</div>
                        <div className="text-2xl font-bold text-upage-elements-textPrimary flex items-center">
                          <span className="i-ph:export-duotone size-6 text-blue-500 dark:text-blue-400 mr-2" />
                          {formatLargeNumber(usageStats.total._sum.inputTokens)}
                        </div>
                      </div>

                      <div className={cardClasses}>
                        <div className="text-sm text-upage-elements-textSecondary mb-1">输出 Token</div>
                        <div className="text-2xl font-bold text-upage-elements-textPrimary flex items-center">
                          <span className="i-ph:import-duotone size-6 text-amber-500 dark:text-amber-400 mr-2" />
                          {formatLargeNumber(usageStats.total._sum.outputTokens)}
                        </div>
                      </div>
                    </div>

                    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
                      <div className={cardClasses}>
                        <h3 className="text-base font-medium text-upage-elements-textPrimary mb-3 flex items-center">
                          <span className="i-ph:chart-pie-slice-duotone size-5 text-purple-500 dark:text-purple-400 mr-2" />
                          请求成功率
                        </h3>
                        <div className="mt-4">
                          <div className="flex justify-between items-center mb-2">
                            <div className="text-3xl font-bold text-upage-elements-textPrimary">
                              {successRate().toFixed(1)}%
                            </div>
                            <div className="text-sm text-upage-elements-textSecondary">
                              {usageStats.byStatus.find((s) => s.status === 'SUCCESS')?._count || 0} /{' '}
                              {usageStats.total._count}
                            </div>
                          </div>
                          <div className="h-2 w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
                            <div
                              className="h-full bg-green-500 dark:bg-green-400 rounded-full"
                              style={{ width: `${Math.min(100, successRate())}%` }}
                            />
                          </div>
                        </div>

                        <div className="mt-4 space-y-2">
                          {usageStats.byStatus.map((status) => (
                            <div key={status.status} className="flex justify-between items-center">
                              <div className="flex items-center">
                                <div
                                  className={classNames('size-2 rounded-full mr-2', {
                                    'bg-green-500 dark:bg-green-400': status.status === 'SUCCESS',
                                    'bg-red-500 dark:bg-red-400': status.status === 'FAILED',
                                    'bg-yellow-500 dark:bg-yellow-400': status.status === 'PENDING',
                                    'bg-gray-500 dark:bg-gray-400': !['SUCCESS', 'FAILED', 'PENDING'].includes(
                                      status.status,
                                    ),
                                  })}
                                />
                                <div className="text-sm text-upage-elements-textSecondary capitalize">
                                  {status.status === 'SUCCESS'
                                    ? '成功'
                                    : status.status === 'FAILED'
                                      ? '失败'
                                      : status.status === 'PENDING'
                                        ? '处理中'
                                        : status.status === 'ABORTED'
                                          ? '中止'
                                          : status.status}
                                </div>
                              </div>
                              <div className="text-sm font-medium text-upage-elements-textPrimary">
                                {formatNumber(status._count)}
                              </div>
                            </div>
                          ))}
                        </div>
                      </div>

                      <div className={cardClasses}>
                        <h3 className="text-base font-medium text-upage-elements-textPrimary mb-3 flex items-center">
                          <span className="i-ph:check-circle-duotone size-5 text-green-500 dark:text-green-400 mr-2" />
                          Token 消耗统计
                        </h3>

                        <div className="space-y-4">
                          <div>
                            <div className="text-sm text-upage-elements-textSecondary mb-1">平均每次请求消耗</div>
                            <div className="text-2xl font-bold text-upage-elements-textPrimary">
                              {formatLargeNumber(avgTokenPerRequest())} Tokens
                            </div>
                          </div>

                          <div className="pt-2 border-t border-upage-elements-borderColor">
                            <div className="text-sm text-upage-elements-textSecondary mb-2">Token 类型分布</div>
                            <div className="space-y-2">
                              <div className="flex justify-between">
                                <div className="text-sm text-upage-elements-textSecondary flex items-center">
                                  <div className="size-2 rounded-full bg-blue-500 dark:bg-blue-400 mr-2" />
                                  输入 Token
                                </div>
                                <div className="text-sm font-medium text-upage-elements-textPrimary">
                                  {formatLargeNumber(usageStats.total._sum.inputTokens)}
                                  <span className="text-xs text-upage-elements-textTertiary ml-1">
                                    (
                                    {usageStats.total._sum.totalTokens
                                      ? (
                                          ((usageStats.total._sum.inputTokens || 0) /
                                            usageStats.total._sum.totalTokens) *
                                          100
                                        ).toFixed(0)
                                      : 0}
                                    %)
                                  </span>
                                </div>
                              </div>

                              <div className="flex justify-between">
                                <div className="text-sm text-upage-elements-textSecondary flex items-center">
                                  <div className="size-2 rounded-full bg-amber-500 dark:bg-amber-400 mr-2" />
                                  输出 Token
                                </div>
                                <div className="text-sm font-medium text-upage-elements-textPrimary">
                                  {formatLargeNumber(usageStats.total._sum.outputTokens)}
                                  <span className="text-xs text-upage-elements-textTertiary ml-1">
                                    (
                                    {usageStats.total._sum.totalTokens
                                      ? (
                                          ((usageStats.total._sum.outputTokens || 0) /
                                            usageStats.total._sum.totalTokens) *
                                          100
                                        ).toFixed(0)
                                      : 0}
                                    %)
                                  </span>
                                </div>
                              </div>

                              <div className="flex justify-between">
                                <div className="text-sm text-upage-elements-textSecondary flex items-center">
                                  <div className="size-2 rounded-full bg-green-500 dark:bg-green-400 mr-2" />
                                  缓存 Token
                                </div>
                                <div className="text-sm font-medium text-upage-elements-textPrimary">
                                  {formatLargeNumber(usageStats.total._sum.cachedTokens)}
                                  <span className="text-xs text-upage-elements-textTertiary ml-1">
                                    (
                                    {usageStats.total._sum.totalTokens
                                      ? (
                                          ((usageStats.total._sum.cachedTokens || 0) /
                                            usageStats.total._sum.totalTokens) *
                                          100
                                        ).toFixed(0)
                                      : 0}
                                    %)
                                  </span>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>

                      <div className={cardClasses}>
                        <h3 className="text-base font-medium text-upage-elements-textPrimary mb-3 flex items-center">
                          <span className="i-ph:trend-up-duotone size-5 text-blue-500 dark:text-blue-400 mr-2" />
                          使用趋势
                        </h3>
                        <div className="space-y-4">
                          {usageStats.byDate.length > 0 ? (
                            <>
                              <div>
                                <div className="text-sm text-upage-elements-textSecondary mb-1">今日请求</div>
                                <div className="text-2xl font-bold text-upage-elements-textPrimary">
                                  {usageStats.byDate.length > 0
                                    ? formatNumber(usageStats.byDate[usageStats.byDate.length - 1].count)
                                    : '0'}
                                </div>
                              </div>

                              <div className="pt-2 border-t border-upage-elements-borderColor">
                                <div className="text-sm text-upage-elements-textSecondary mb-2">最近趋势</div>
                                <div className="text-sm text-upage-elements-textTertiary">
                                  {usageStats.byDate.length > 1 ? (
                                    (() => {
                                      const current = usageStats.byDate[usageStats.byDate.length - 1].count;
                                      const previous = usageStats.byDate[usageStats.byDate.length - 2].count;
                                      const diff = current - previous;
                                      const percentage = previous !== 0 ? (diff / previous) * 100 : 0;

                                      return (
                                        <div className="flex items-center">
                                          <span className="text-upage-elements-textSecondary">较前一日:</span>
                                          <span
                                            className={classNames('ml-1 flex items-center', {
                                              'text-green-500 dark:text-green-400': diff > 0,
                                              'text-red-500 dark:text-red-400': diff < 0,
                                              'text-upage-elements-textTertiary': diff === 0,
                                            })}
                                          >
                                            {diff > 0 ? (
                                              <span className="i-ph:arrow-up size-3.5 mr-0.5"></span>
                                            ) : diff < 0 ? (
                                              <span className="i-ph:arrow-down size-3.5 mr-0.5"></span>
                                            ) : (
                                              <span className="i-ph:minus size-3.5 mr-0.5"></span>
                                            )}
                                            {Math.abs(percentage).toFixed(0)}%
                                          </span>
                                        </div>
                                      );
                                    })()
                                  ) : (
                                    <span>尚无对比数据</span>
                                  )}
                                </div>
                              </div>
                            </>
                          ) : (
                            <div className="flex items-center justify-center h-full py-6">
                              <span className="text-sm text-upage-elements-textSecondary">暂无数据</span>
                            </div>
                          )}
                        </div>
                      </div>
                    </div>

                    <div className={classNames(cardClasses, 'p-0 overflow-hidden')}>
                      <div className="p-4 border-b border-upage-elements-borderColor">
                        <h3 className="text-base font-medium text-upage-elements-textPrimary flex items-center">
                          <span className="i-ph:chart-line-up-duotone size-5 text-purple-500 dark:text-purple-400 mr-2" />
                          使用统计图表
                        </h3>
                      </div>
                      <div className="p-4">
                        <ChatUsageVisualization usageStats={usageStats} />
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </div>
          </motion.div>
        </RadixDialog.Content>
      </RadixDialog.Portal>
    </RadixDialog.Root>
  );
});
