import {
  AppstoreOutlined,
  CheckCircleOutlined,
  ClockCircleOutlined,
  CloseCircleOutlined,
  PlusOutlined,
} from "@ant-design/icons";
import { Button, Empty, Segmented, Skeleton } from "antd";
import { useMemo, useState } from "react";

import type { Material } from "../types";

import { MaterialCard } from "./MaterialCard";
import { MaterialGroup } from "./MaterialGroup";

type DateGroup = "earlier" | "thisMonth" | "thisWeek" | "today" | "yesterday";

interface MaterialListProps {
  loading: boolean;
  materials: readonly Material[];
  onAddClick: () => void;
  onDelete: (id: string) => void;
  onSelect: (id: string) => void;
  selectedId: null | string;
}

const GROUP_LABELS: Record<DateGroup, string> = {
  earlier: "更早",
  thisMonth: "本月",
  thisWeek: "本周",
  today: "今天",
  yesterday: "昨天",
};

const GROUP_ORDER: readonly DateGroup[] = ["today", "yesterday", "thisWeek", "thisMonth", "earlier"];

interface MaterialGroupData {
  items: Material[];
  key: DateGroup;
}

function getDateGroup(dateStr: string, now: Date): DateGroup {
  const date = new Date(dateStr);
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const yesterday = new Date(today.getTime() - 86_400_000);
  const dateDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());

  if (dateDay.getTime() >= today.getTime()) return "today";
  if (dateDay.getTime() >= yesterday.getTime()) return "yesterday";

  const dayOfWeek = today.getDay();
  const mondayOffset = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
  const monday = new Date(today.getTime() - mondayOffset * 86_400_000);
  if (dateDay.getTime() >= monday.getTime()) return "thisWeek";

  if (dateDay.getFullYear() === today.getFullYear() && dateDay.getMonth() === today.getMonth()) {
    return "thisMonth";
  }

  return "earlier";
}

function groupMaterialsByDate(materials: readonly Material[]): MaterialGroupData[] {
  const now = new Date();
  const groups = new Map<DateGroup, Material[]>();

  for (const m of materials) {
    const group = getDateGroup(m.createdAt, now);
    if (!groups.has(group)) groups.set(group, []);
    groups.get(group)!.push(m);
  }

  return GROUP_ORDER.map((key) => ({ items: groups.get(key) ?? [], key }));
}

const STATUS_FILTER_OPTIONS = [
  { icon: <AppstoreOutlined />, label: "全部", value: "all" },
  { color: "#faad14", icon: <ClockCircleOutlined />, label: "待审核", value: "pending" },
  { color: "#52c41a", icon: <CheckCircleOutlined />, label: "已通过", value: "approved" },
  { color: "#ff4d4f", icon: <CloseCircleOutlined />, label: "已放弃", value: "discarded" },
] as const;

type FilterValue = (typeof STATUS_FILTER_OPTIONS)[number]["value"];

export function MaterialList({ loading, materials, onAddClick, onDelete, onSelect, selectedId }: MaterialListProps) {
  const [filterStatus, setFilterStatus] = useState<FilterValue>("all");

  const filteredMaterials = useMemo(() => {
    if (filterStatus === "all") return materials;
    return materials.filter((m) => m.status === filterStatus);
  }, [materials, filterStatus]);

  const groupedMaterials = useMemo(() => groupMaterialsByDate(filteredMaterials), [filteredMaterials]);

  const segmentedOptions = useMemo(
    () =>
      STATUS_FILTER_OPTIONS.map((opt) => ({
        label: (
          <span>
            {"color" in opt && opt.color ? <span style={{ color: opt.color }}>{opt.icon}</span> : opt.icon}
            <span className="app-inbox-filter-count">{getStatusCount(materials, opt.value)}</span>
          </span>
        ),
        value: opt.value,
      })),
    [materials],
  );

  const showAllGroups = filterStatus === "all";

  return (
    <div className="app-inbox-sidebar">
      <Button block icon={<PlusOutlined />} onClick={onAddClick} type="primary">
        新增素材
      </Button>
      <Segmented block onChange={(value) => setFilterStatus(value)} options={segmentedOptions} value={filterStatus} />
      <div className="app-inbox-list">
        {loading ? (
          <Skeleton active paragraph={{ rows: 6 }} title={false} />
        ) : materials.length === 0 ? (
          <Empty description="暂无素材" image={Empty.PRESENTED_IMAGE_SIMPLE} />
        ) : filteredMaterials.length === 0 ? (
          <Empty description="当前筛选条件下无素材" image={Empty.PRESENTED_IMAGE_SIMPLE} />
        ) : (
          groupedMaterials.map((group) => {
            if (!showAllGroups && group.items.length === 0) return null;
            return (
              <MaterialGroup
                count={group.items.length}
                emptyText="暂无"
                key={group.key}
                label={GROUP_LABELS[group.key]}
              >
                {group.items.map((material) => (
                  <MaterialCard
                    key={material.id}
                    material={material}
                    onDelete={() => onDelete(material.id)}
                    onSelect={() => onSelect(material.id)}
                    selected={material.id === selectedId}
                  />
                ))}
              </MaterialGroup>
            );
          })
        )}
      </div>
    </div>
  );
}

function getStatusCount(materials: readonly Material[], status: string): number {
  if (status === "all") return materials.length;
  return materials.filter((m) => m.status === status).length;
}
