import { useEffect, useMemo, useState } from "react"
import type { ReactNode } from "react"
import {
  DeleteOutlined,
  DownOutlined,
  GlobalOutlined,
  LockOutlined,
  PictureOutlined,
  PlusOutlined,
  SaveOutlined,
  SettingOutlined,
  UpOutlined,
  UploadOutlined,
  VideoCameraOutlined,
} from "@ant-design/icons"
import {
  Button,
  Card,
  Col,
  Empty,
  Form,
  Grid,
  Input,
  Row,
  Segmented,
  Space,
  Statistic,
  Tag,
  Typography,
  Upload,
  theme,
} from "antd"
import { PageSkeleton, type SkeletonSpec } from "../../utils/skeleton"
import {
  getFrontendConfig,
  updateFrontendConfig,
  uploadBrandLogo,
  uploadFrontendAsset,
} from "../api/settings"
import { toast } from "../../utils/toast"

const { Title, Text } = Typography

const PAGE_SKELETON: SkeletonSpec[] = [
  { type: "header", title: 200, subtitle: 280 },
  { type: "grid", cols: 4, count: 4, gap: 12, item: { type: "card", h: 90 } },
  { type: "card", h: 480 },
]

interface HeroSlide {
  nav_title: string
  kicker: string
  title: string
  description: string
  action: string
  href: string
  background: string
}

interface FrontendConfigForm {
  site_name: string
  logo_url: string
  hero_video_url: string
  hero_title: string
  hero_description: string
  hero_slides: HeroSlide[]
  auth_background_type: "image" | "video"
  auth_background_url: string
}

type SectionKey = "brand" | "slides" | "video" | "auth"

interface SectionMeta {
  key: SectionKey
  title: string
  description: string
  icon: ReactNode
}

const SECTIONS: SectionMeta[] = [
  { key: "brand", title: "站点品牌", description: "站点名称与 Logo", icon: <SettingOutlined /> },
  { key: "slides", title: "首页轮播图", description: "首页首屏轮播内容", icon: <PictureOutlined /> },
  { key: "video", title: "首页视频覆盖", description: "视频优先于轮播图展示", icon: <VideoCameraOutlined /> },
  { key: "auth", title: "登录页背景", description: "登录 / 注册页视觉背景", icon: <LockOutlined /> },
]

function fileIsImage(file: File) {
  return file.type.startsWith("image/")
}

function isVideoUrl(url: string) {
  return /\.(mp4|webm)(\?|$)/i.test(url)
}

// ─── Shared sub-components ───────────────────────────────────────────────────

function NavItem({ active, item, onClick }: { active: boolean; item: SectionMeta; onClick: () => void }) {
  const { token } = theme.useToken()
  return (
    <button
      type="button"
      onClick={onClick}
      style={{
        all: "unset",
        display: "flex",
        alignItems: "center",
        gap: 10,
        width: "100%",
        padding: "10px 12px",
        borderRadius: 8,
        cursor: "pointer",
        background: active ? token.colorPrimaryBg : "transparent",
        border: `1px solid ${active ? token.colorPrimaryBorder : "transparent"}`,
        transition: "all 0.15s",
        boxSizing: "border-box",
      }}
    >
      <span style={{ fontSize: 16, color: active ? token.colorPrimary : token.colorTextTertiary, lineHeight: 1, flexShrink: 0 }}>
        {item.icon}
      </span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div>
          <Text strong style={{ fontSize: 13, color: active ? token.colorPrimary : token.colorText }}>
            {item.title}
          </Text>
        </div>
        <div>
          <Text type="secondary" style={{ fontSize: 11 }}>{item.description}</Text>
        </div>
      </div>
    </button>
  )
}

function SectionHeader({ meta }: { meta: SectionMeta }) {
  const { token } = theme.useToken()
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 10,
        marginBottom: 20,
        paddingBottom: 16,
        borderBottom: `1px solid ${token.colorBorderSecondary}`,
      }}
    >
      <div
        style={{
          width: 36,
          height: 36,
          borderRadius: 8,
          background: token.colorPrimaryBg,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          color: token.colorPrimary,
          fontSize: 16,
          flexShrink: 0,
        }}
      >
        {meta.icon}
      </div>
      <div>
        <Text strong style={{ fontSize: 15, display: "block", lineHeight: "1.3" }}>{meta.title}</Text>
        <Text type="secondary" style={{ fontSize: 12 }}>{meta.description}</Text>
      </div>
    </div>
  )
}

// 图片/视频预览卡片：替代原来的虚线边框小方块
function MediaPreviewCard({
  src,
  kind,
  ratio = "16 / 9",
  emptyLabel,
  uploading,
  accept,
  onUpload,
}: {
  src: string
  kind: "image" | "video" | "auto"
  ratio?: string
  emptyLabel: string
  uploading: boolean
  accept: string
  onUpload: (file: File) => void
}) {
  const { token } = theme.useToken()
  const resolvedKind = kind === "auto" ? (isVideoUrl(src) ? "video" : "image") : kind
  return (
    <div
      style={{
        borderRadius: 12,
        border: `1px solid ${token.colorBorderSecondary}`,
        background: token.colorFillAlter,
        overflow: "hidden",
      }}
    >
      <div
        style={{
          aspectRatio: ratio,
          background: src ? "#0f172a" : token.colorFillTertiary,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          position: "relative",
        }}
      >
        {src ? (
          resolvedKind === "video" ? (
            <video src={src} muted loop autoPlay playsInline style={{ width: "100%", height: "100%", objectFit: "cover" }} />
          ) : (
            <img src={src} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
          )
        ) : (
          <Space orientation="vertical" align="center" size={6}>
            <span style={{ fontSize: 26, color: token.colorTextQuaternary }}>
              {kind === "video" ? <VideoCameraOutlined /> : <PictureOutlined />}
            </span>
            <Text type="secondary" style={{ fontSize: 12 }}>{emptyLabel}</Text>
          </Space>
        )}
      </div>
      <div style={{ padding: 10, borderTop: `1px solid ${token.colorBorderSecondary}` }}>
        <Upload
          accept={accept}
          showUploadList={false}
          beforeUpload={(file) => {
            onUpload(file)
            return Upload.LIST_IGNORE
          }}
        >
          <Button block size="small" icon={<UploadOutlined />} loading={uploading}>
            {src ? "替换资源" : "上传资源"}
          </Button>
        </Upload>
      </div>
    </div>
  )
}

// ─── Main component ──────────────────────────────────────────────────────────

export default function AdminFrontendConfig() {
  const { token } = theme.useToken()
  const screens = Grid.useBreakpoint()
  const [form] = Form.useForm<FrontendConfigForm>()
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [uploading, setUploading] = useState<string | null>(null)
  const [activeSection, setActiveSection] = useState<SectionKey>("brand")

  const authBackgroundType = Form.useWatch("auth_background_type", form)
  const logoUrl = Form.useWatch("logo_url", form)
  const siteName = Form.useWatch("site_name", form)
  const authBackgroundUrl = Form.useWatch("auth_background_url", form)
  const heroVideoUrl = Form.useWatch("hero_video_url", form)
  const heroSlides = Form.useWatch("hero_slides", form) as HeroSlide[] | undefined

  useEffect(() => {
    setLoading(true)
    void getFrontendConfig()
      .then((res) => form.setFieldsValue(res.data as FrontendConfigForm))
      .catch(() => toast.error("加载前端配置失败"))
      .finally(() => setLoading(false))
  }, [form])

  const uploadAsset = async (file: File, fieldPath: (string | number)[]) => {
    if (file.size > 30 * 1024 * 1024) {
      toast.error("资源文件不能超过 30MB")
      return
    }
    setUploading(fieldPath.join("."))
    try {
      const res = await uploadFrontendAsset(file)
      form.setFieldValue(fieldPath as never, res.data?.url ?? "")
      toast.success("资源已上传")
    } catch {
      toast.error("资源上传失败")
    } finally {
      setUploading(null)
    }
  }

  const uploadLogo = async (file: File) => {
    if (!fileIsImage(file) || file.size > 2 * 1024 * 1024) {
      toast.error("Logo 仅支持 2MB 以内的图片")
      return
    }
    setUploading("logo")
    try {
      const res = await uploadBrandLogo(file)
      if (res.data) form.setFieldsValue(res.data as FrontendConfigForm)
      toast.success("站点 Logo 已更新")
    } catch {
      toast.error("Logo 上传失败")
    } finally {
      setUploading(null)
    }
  }

  const handleSave = async () => {
    try {
      setSaving(true)
      const values = await form.validateFields()
      await updateFrontendConfig({
        "platform.site_name": values.site_name,
        "frontend.hero_video_url": values.hero_video_url,
        "frontend.hero_title": values.hero_title,
        "frontend.hero_description": values.hero_description,
        "frontend.hero_slides": values.hero_slides,
        "frontend.auth_background_type": values.auth_background_type,
        "frontend.auth_background_url": values.auth_background_url,
      } as never)
      toast.success("前端配置已保存")
    } catch {
      toast.error("保存前端配置失败")
    } finally {
      setSaving(false)
    }
  }

  const stats = useMemo(() => [
    { title: "站点名称", value: siteName || "未设置", icon: <GlobalOutlined />, color: token.colorPrimary },
    { title: "站点 Logo", value: logoUrl ? "已上传" : "未上传", icon: <PictureOutlined />, color: logoUrl ? token.colorSuccess : token.colorTextTertiary },
    { title: "首页轮播图", value: heroSlides?.length ?? 0, suffix: "张", icon: <PictureOutlined />, color: token.colorPrimary },
    { title: "登录页背景", value: authBackgroundType === "video" ? "视频" : "图片", icon: <LockOutlined />, color: token.colorWarning },
  ], [siteName, logoUrl, heroSlides, authBackgroundType, token])

  const paneStyle = screens.md
    ? { height: "calc(100vh - 340px)", minHeight: 440, maxHeight: 640, overflowY: "auto" as const }
    : {}

  const brandContent = (
    <Row gutter={[24, 16]} align="top">
      <Col xs={24} md={14}>
        <Form.Item name="site_name" label="站点名称" rules={[{ required: true, message: "请输入站点名称" }]}>
          <Input maxLength={40} placeholder="例如：云服务中心" />
        </Form.Item>
        <Text type="secondary" style={{ fontSize: 12 }}>
          将展示在浏览器标题、后台侧边栏和前台导航中。
        </Text>
      </Col>
      <Col xs={24} md={10}>
        <Text style={{ fontSize: 13, display: "block", marginBottom: 8 }}>站点 Logo</Text>
        <Form.Item name="logo_url" hidden><Input /></Form.Item>
        <MediaPreviewCard
          src={logoUrl || ""}
          kind="image"
          ratio="3 / 1"
          emptyLabel="尚未上传 Logo"
          uploading={uploading === "logo"}
          accept="image/png,image/jpeg,image/webp,image/svg+xml"
          onUpload={(file) => void uploadLogo(file)}
        />
      </Col>
    </Row>
  )

  const slidesContent = (
    <Form.List name="hero_slides">
      {(fields, { add, remove, move }) => (
        <Space orientation="vertical" size={16} style={{ width: "100%" }}>
          {fields.length === 0 && (
            <Card variant="outlined" style={{ background: token.colorFillAlter }}>
              <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无轮播图，点击下方按钮添加" />
            </Card>
          )}
          {fields.map((field, index) => {
            const background = form.getFieldValue(["hero_slides", field.name, "background"])
            const fieldKey = `slide.${field.name}`
            return (
              <Card
                key={field.key}
                variant="outlined"
                styles={{ body: { padding: 18 } }}
                style={{ borderRadius: 12 }}
              >
                <Row gutter={[20, 12]}>
                  <Col xs={24} lg={8}>
                    <Form.Item name={[field.name, "background"]} hidden><Input /></Form.Item>
                    <MediaPreviewCard
                      src={background || ""}
                      kind="image"
                      emptyLabel="尚未上传背景图"
                      uploading={uploading === fieldKey}
                      accept="image/png,image/jpeg,image/webp"
                      onUpload={(file) => void uploadAsset(file, ["hero_slides", field.name, "background"])}
                    />
                  </Col>
                  <Col xs={24} lg={16}>
                    <Space style={{ width: "100%", justifyContent: "space-between", marginBottom: 8 }}>
                      <Tag color="blue" style={{ margin: 0 }}>轮播图 #{index + 1}</Tag>
                      <Space size={4}>
                        <Button size="small" type="text" icon={<UpOutlined />} disabled={index === 0} onClick={() => move(index, index - 1)} />
                        <Button size="small" type="text" icon={<DownOutlined />} disabled={index === fields.length - 1} onClick={() => move(index, index + 1)} />
                        <Button size="small" type="text" danger icon={<DeleteOutlined />} onClick={() => remove(field.name)} />
                      </Space>
                    </Space>
                    <Row gutter={[12, 0]}>
                      <Col xs={24} md={12}><Form.Item name={[field.name, "nav_title"]} label="导航标题" rules={[{ required: true }]}><Input /></Form.Item></Col>
                      <Col xs={24} md={12}><Form.Item name={[field.name, "kicker"]} label="副标题"><Input /></Form.Item></Col>
                      <Col xs={24}><Form.Item name={[field.name, "title"]} label="主标题" rules={[{ required: true }]}><Input /></Form.Item></Col>
                      <Col xs={24}><Form.Item name={[field.name, "description"]} label="说明"><Input.TextArea rows={2} /></Form.Item></Col>
                      <Col xs={24} md={12}><Form.Item name={[field.name, "action"]} label="按钮文字"><Input /></Form.Item></Col>
                      <Col xs={24} md={12}><Form.Item name={[field.name, "href"]} label="跳转地址"><Input placeholder="/store" /></Form.Item></Col>
                    </Row>
                  </Col>
                </Row>
              </Card>
            )
          })}
          <Button
            type="dashed"
            block
            icon={<PlusOutlined />}
            onClick={() => add({ nav_title: "新轮播图", title: "新轮播标题", href: "/store", action: "立即查看" })}
          >
            新增轮播图
          </Button>
        </Space>
      )}
    </Form.List>
  )

  const videoContent = (
    <Row gutter={[24, 16]}>
      <Col xs={24} lg={10}>
        <Form.Item name="hero_video_url" hidden><Input /></Form.Item>
        <MediaPreviewCard
          src={heroVideoUrl || ""}
          kind="video"
          emptyLabel="留空则使用轮播图"
          uploading={uploading === "hero_video_url"}
          accept="video/mp4,video/webm"
          onUpload={(file) => void uploadAsset(file, ["hero_video_url"])}
        />
        <Text type="secondary" style={{ fontSize: 12, marginTop: 8, display: "block" }}>
          上传后会覆盖轮播图背景；留空则使用轮播图。
        </Text>
      </Col>
      <Col xs={24} lg={14}>
        <Form.Item name="hero_title" label="视频标题"><Input maxLength={80} /></Form.Item>
        <Form.Item name="hero_description" label="视频说明"><Input.TextArea rows={4} maxLength={200} /></Form.Item>
      </Col>
    </Row>
  )

  const authContent = (
    <Row gutter={[24, 16]}>
      <Col xs={24} lg={10}>
        <Form.Item name="auth_background_type" label="背景类型">
          <Segmented block options={[{ value: "video", label: "视频" }, { value: "image", label: "图片" }]} />
        </Form.Item>
        <Form.Item name="auth_background_url" hidden><Input /></Form.Item>
        <MediaPreviewCard
          src={authBackgroundUrl || ""}
          kind={authBackgroundType === "image" ? "image" : "video"}
          ratio="16 / 10"
          emptyLabel={authBackgroundType === "image" ? "尚未上传背景图片" : "尚未上传背景视频"}
          uploading={uploading === "auth_background_url"}
          accept={authBackgroundType === "image" ? "image/png,image/jpeg,image/webp" : "video/mp4,video/webm"}
          onUpload={(file) => void uploadAsset(file, ["auth_background_url"])}
        />
      </Col>
      <Col xs={24} lg={14}>
        <Text type="secondary" style={{ fontSize: 13, lineHeight: 1.9 }}>
          登录页和注册页共用该背景资源。视频背景推荐 1920 x 1080 像素、时长 10-20 秒并循环播放；图片背景同尺寸即可，支持 PNG、JPG、WebP。
        </Text>
      </Col>
    </Row>
  )

  const contentMap: Record<SectionKey, ReactNode> = {
    brand: brandContent,
    slides: slidesContent,
    video: videoContent,
    auth: authContent,
  }

  const activeMeta = SECTIONS.find((s) => s.key === activeSection) ?? SECTIONS[0]

  return (
    <PageSkeleton loading={loading} spec={PAGE_SKELETON} gap={24}>
      <Space orientation="vertical" size={20} style={{ width: "100%" }}>
        <Row gutter={[16, 16]} align="bottom" justify="space-between">
          <Col>
            <Title level={3} style={{ margin: 0 }}>前端配置</Title>
            <Text type="secondary">集中管理站点品牌、首页首屏和登录页视觉资源。</Text>
          </Col>
          <Col>
            <Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={() => void handleSave()}>
              保存发布
            </Button>
          </Col>
        </Row>

        <Row gutter={[16, 16]}>
          {stats.map((item) => (
            <Col xs={24} sm={12} xl={6} key={item.title}>
              <Card variant="outlined">
                <Space align="start" style={{ width: "100%", justifyContent: "space-between" }}>
                  <Statistic title={item.title} value={item.value} suffix={item.suffix} />
                  <span style={{ color: item.color, fontSize: 22 }}>{item.icon}</span>
                </Space>
              </Card>
            </Col>
          ))}
        </Row>

        <Form form={form} layout="vertical">
          <Card variant="outlined" styles={{ body: { padding: 0 } }}>
            <Row gutter={0}>
              <Col
                xs={24} md={7} xl={6}
                style={{
                  borderRight: screens.md ? `1px solid ${token.colorBorderSecondary}` : "none",
                  borderBottom: !screens.md ? `1px solid ${token.colorBorderSecondary}` : "none",
                }}
              >
                <div style={{ ...paneStyle, padding: 10 }}>
                  <Space orientation="vertical" size={4} style={{ width: "100%" }}>
                    {SECTIONS.map((item) => (
                      <NavItem
                        key={item.key}
                        active={item.key === activeSection}
                        item={item}
                        onClick={() => setActiveSection(item.key)}
                      />
                    ))}
                  </Space>
                </div>
              </Col>

              <Col xs={24} md={17} xl={18}>
                <div style={{ ...paneStyle, padding: screens.md ? "24px 28px" : "20px 16px" }}>
                  <SectionHeader meta={activeMeta} />
                  {contentMap[activeSection]}
                </div>
              </Col>
            </Row>
          </Card>
        </Form>
      </Space>
    </PageSkeleton>
  )
}
