import { Layout } from "@/components/Layout";
import type { Route } from "./+types/home";
import { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { treaty } from "@elysiajs/eden";
import type { App } from "@elysia/src";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import { formatDateTime } from "@/components/SearchResults";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Card } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";

// @ts-ignore idk
const app = treaty<App>(import.meta.env.VITE_API_URL!);

type CloseMilestoneInfo = Awaited<ReturnType<ReturnType<(typeof app.songs)["close-milestone"]>["get"]>>["data"];
type CloseMilestoneError = Awaited<ReturnType<ReturnType<(typeof app.songs)["close-milestone"]>["get"]>>["error"];

export function meta({}: Route.MetaArgs) {
	return [{ title: "中V档案馆" }];
}

type MilestoneType = "dendou" | "densetsu" | "shinwa";

const milestoneConfig = {
	dendou: { name: "殿堂", range: [90000, 99999], target: 100000 },
	densetsu: { name: "传说", range: [900000, 999999], target: 1000000 },
	shinwa: { name: "神话", range: [5000000, 9999999], target: 10000000 },
};

function formatHours(hours: number): string {
	if (hours >= 24 * 14) return `${Math.floor(hours / 24)} 天`;
	if (hours >= 24) return `${Math.floor(hours / 24)} 天 ${Math.floor(hours % 24)} 小时`;
	if (hours >= 1) return `${Math.floor(hours)} 时 ${Math.round((hours % 1) * 60)} 分`;
	return `${Math.round(hours * 60)} 分钟`;
}

function addHoursToNow(hours: number): string {
	const d = new Date();
	d.setHours(d.getHours() + hours);
	return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, "0")}-${d.getDate().toString().padStart(2, "0")} ${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
}

export default function Home() {
	const [input, setInput] = useState("");
	const [milestoneType, setMilestoneType] = useState<MilestoneType>("shinwa");
	const [closeMilestoneInfo, setCloseMilestoneInfo] = useState<CloseMilestoneInfo>();
	const [closeMilestoneError, setCloseMilestoneError] = useState<CloseMilestoneError>();
	const [isLoading, setIsLoading] = useState(false);

	const fetchMilestoneData = async (type: MilestoneType) => {
		setIsLoading(true);
		setCloseMilestoneError(undefined);
		const { data, error } = await app.songs["close-milestone"]({ type }).get();
		if (error) {
			setCloseMilestoneError(error);
		} else {
			setCloseMilestoneInfo(data);
		}
		setIsLoading(false);
	};

	useEffect(() => {
		fetchMilestoneData(milestoneType);
	}, [milestoneType]);

	const MilestoneVideoCard = ({ video }: { video: NonNullable<CloseMilestoneInfo>[number] }) => {
		const config = milestoneConfig[milestoneType];
		const remainingViews = config.target - video.eta.currentViews;
		const progressPercentage = (video.eta.currentViews / config.target) * 100;

		return (
			<Card className="px-3 max-md:py-3 md:px-4 my-4 gap-0">
				<div className="w-full flex items-start space-x-4 mb-4">
					{video.bilibili_metadata.coverUrl && (
						<img
							src={video.bilibili_metadata.coverUrl}
							alt="视频封面"
							className="h-25 w-40 rounded-sm object-cover flex-shrink-0"
							referrerPolicy="no-referrer"
						/>
					)}
					<div className="flex flex-col w-full justify-between">
						<h3 className="text-sm sm:text-lg font-medium line-clamp-2 text-wrap mb-2">
							<a href={`/song/av${video.bilibili_metadata.aid}/info`} className="hover:underline">
								{video.bilibili_metadata.title}
							</a>
						</h3>

						<div className="space-y-2 text-xs text-muted-foreground">
							<div className="flex items-center justify-between">
								<span>当前播放: {video.eta.currentViews.toLocaleString()}</span>
								<span>目标: {config.target.toLocaleString()}</span>
							</div>

							<Progress value={progressPercentage} />
						</div>
					</div>
				</div>
				<div className="grid grid-cols-2 gap-5 text-xs text-muted-foreground mb-2">
					<div>
						<p>剩余播放: {remainingViews.toLocaleString()}</p>
						<p>预计达成: {formatHours(video.eta.eta)}</p>
					</div>
					<div>
						<p>播放速度: {Math.round(video.eta.speed)}/小时</p>
						<p>达成时间: {addHoursToNow(video.eta.eta)}</p>
					</div>
				</div>

				<div className="flex gap-4 text-xs text-muted-foreground">
					{video.bilibili_metadata.publishedAt && (
						<span className="stat-num">
							发布于 {formatDateTime(new Date(video.bilibili_metadata.publishedAt))}
						</span>
					)}
					<a
						href={`https://www.bilibili.com/video/av${video.bilibili_metadata.aid}`}
						target="_blank"
						rel="noopener noreferrer"
						className="text-pink-400 text-xs hover:underline"
					>
						观看视频
					</a>
					<a
						href={`/song/av${video.bilibili_metadata.aid}/info`}
						className="text-xs text-secondary-foreground hover:underline"
					>
						查看详情
					</a>
				</div>
			</Card>
		);
	};

	const MilestoneVideos = () => {
		if (isLoading) {
			return (
				<div className="space-y-4">
					{[1, 2, 3].map((i) => (
						<div
							key={i}
							className="bg-white dark:bg-neutral-800 rounded-lg shadow-sm border border-gray-200 dark:border-neutral-700 p-4"
						>
							<div className="flex items-start space-x-4">
								<Skeleton className="h-21 w-36 rounded-sm" />
								<div className="flex-1 space-y-2">
									<Skeleton className="h-6 w-3/4" />
									<Skeleton className="h-4 w-full" />
									<Skeleton className="h-4 w-2/3" />
									<Skeleton className="h-4 w-1/2" />
								</div>
							</div>
						</div>
					))}
				</div>
			);
		}

		if (closeMilestoneError) {
			return (
				<div className="text-center py-8">
					<p className="text-red-500">加载失败: {closeMilestoneError.value?.message || "未知错误"}</p>
					<Button variant="outline" className="mt-4" onClick={() => fetchMilestoneData(milestoneType)}>
						重试
					</Button>
				</div>
			);
		}

		if (!closeMilestoneInfo || closeMilestoneInfo.length === 0) {
			return (
				<div className="text-center py-8">
					<p className="text-secondary-foreground">暂无接近{milestoneConfig[milestoneType].name}的视频</p>
				</div>
			);
		}

		return (
			<div className="space-y-4">
				<p className="text-xs text-muted-foreground">
					找到 {closeMilestoneInfo.length} 个接近{milestoneConfig[milestoneType].name}的视频
				</p>
				<ScrollArea className="h-140 w-full">
					{closeMilestoneInfo.map((video) => (
						<MilestoneVideoCard key={video.bilibili_metadata.aid} video={video} />
					))}
				</ScrollArea>
			</div>
		);
	};

	return (
		<Layout>
			<h2 className="text-2xl mt-5 mb-6">小工具</h2>
			<div className="flex max-sm:flex-col sm:items-center gap-7 mb-8">
				<Button>
					<a href="/util/time-calculator">时间计算器</a>
				</Button>

				<div className="flex sm:w-96 gap-3">
					<Input placeholder="输入BV号或av号" value={input} onChange={(e) => setInput(e.target.value)} />
					<Button>
						<a href={`/song/${input}/add`}>收录视频</a>
					</Button>
				</div>
			</div>

			<h2 className="text-2xl mb-4">即将达成里程碑</h2>
			<div className="flex items-center gap-4 mb-6">
				<Select value={milestoneType} onValueChange={(value: MilestoneType) => setMilestoneType(value)}>
					<SelectTrigger className="w-20">
						<SelectValue placeholder="成就" />
					</SelectTrigger>
					<SelectContent>
						<SelectItem value="dendou">殿堂</SelectItem>
						<SelectItem value="densetsu">传说</SelectItem>
						<SelectItem value="shinwa">神话</SelectItem>
					</SelectContent>
				</Select>
				<span className="text-xs text-muted-foreground">
					播放量在 {milestoneConfig[milestoneType].range[0].toLocaleString()} -{" "}
					{milestoneConfig[milestoneType].range[1].toLocaleString()} 之间，即将达成
					{milestoneConfig[milestoneType].name}
				</span>
			</div>

			<MilestoneVideos />
		</Layout>
	);
}
