import { useEffect, useMemo, useRef, useState } from "react"
import type { TaskPanelArtifact, TaskPanelItem } from "@qjclaw/shared-types"
import { renderExpertIcon } from "../../components/icons/AppIcons"
import { Panel } from "../../components/ui/Panel"
import { ScrollArea } from "../../components/ui/ScrollArea"
import type { ExpertVisualKey } from "../shell/ExpertTree"
import { getDefaultTaskPanelDate, getVisibleTaskPanelArtifacts, loadTaskPanelItems, summarizeTaskPanelItems } from "./taskPanelData"

function resolveTaskExpertIconKey(expertName: string): ExpertVisualKey {
  const seed = expertName.toLowerCase()
  if (/xiaohongshu|xhs|rednote|小红书/.test(seed)) {
    return "xiaohongshu"
  }
  if (/douyin|抖音/.test(seed)) {
    return "douyin"
  }
  if (/tiktok/.test(seed)) {
    return "tiktok"
  }
  if (/wechat|weixin|公众号|微信/.test(seed)) {
    return "wechat"
  }
  if (/zhihu|知乎/.test(seed)) {
    return "zhihu"
  }
  if (/content-account|planner|账号规划|内容账号规划/.test(seed)) {
    return "planner"
  }
  if (/precision-leads|线索|lead/.test(seed)) {
    return "leads"
  }
  if (/sales-champion|销售冠军|销冠|sales champion/.test(seed)) {
    return "sales"
  }
  if (/poster|海报/.test(seed)) {
    return "poster"
  }
  if (/(^|[\s-])x($|[\s-])|twitter/.test(seed)) {
    return "x"
  }
  if (/geo/.test(seed)) {
    return "geo"
  }
  if (/browser|automation|chrome|playwright|web|浏览器|自动化/.test(seed)) {
    return "browser"
  }
  return "general"
}

interface TaskPanelOutputItem {
  artifact: TaskPanelArtifact
  task: TaskPanelItem
}

function TaskPanelMetricIcon({ kind }: { kind: "credits" | "messages" | "artifacts" | "employees" }) {
  if (kind === "credits") {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M12 3.75 14.3 8.4l5.1.74-3.7 3.6.87 5.08L12 15.42l-4.57 2.4.87-5.08-3.7-3.6 5.1-.74L12 3.75Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.7" />
      </svg>
    )
  }
  if (kind === "messages") {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M5.25 6.75A2.75 2.75 0 0 1 8 4h8a2.75 2.75 0 0 1 2.75 2.75v5.5A2.75 2.75 0 0 1 16 15h-3.3l-3.25 3.05c-.44.41-1.15.1-1.15-.51V15H8a2.75 2.75 0 0 1-2.75-2.75v-5.5Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.7" />
        <path d="M8.75 8.4h6.5M8.75 11.25h4.5" fill="none" stroke="currentColor" strokeLinecap="round" strokeWidth="1.6" />
      </svg>
    )
  }
  if (kind === "artifacts") {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M7 4.25h6.35L18 8.9v8.85A2.25 2.25 0 0 1 15.75 20H7a2.25 2.25 0 0 1-2.25-2.25V6.5A2.25 2.25 0 0 1 7 4.25Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.7" />
        <path d="M13.25 4.5v3.35c0 .7.57 1.27 1.27 1.27h3.25M8.3 12.2h6.6M8.3 15.45h4.4" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.55" />
      </svg>
    )
  }
  return (
    <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
      <path d="M8.75 11.25a3.25 3.25 0 1 1 0-6.5 3.25 3.25 0 0 1 0 6.5Zm6.75.5a2.75 2.75 0 1 1 0-5.5 2.75 2.75 0 0 1 0 5.5Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.65" />
      <path d="M3.9 18.75a4.85 4.85 0 0 1 9.7 0m-.55-1.3a4.05 4.05 0 0 1 7.05 1.3" fill="none" stroke="currentColor" strokeLinecap="round" strokeWidth="1.65" />
    </svg>
  )
}

function TaskPanelOutputIcon({ artifact }: { artifact: TaskPanelArtifact }) {
  const normalizedKind = [artifact.kind, artifact.name, artifact.path, artifact.url].filter(Boolean).join(" ").toLowerCase()
  if (/视频|video|mp4|mov|m4v|avi|webm/.test(normalizedKind)) {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M5.25 7.25A2.25 2.25 0 0 1 7.5 5h6.25A2.25 2.25 0 0 1 16 7.25v.55l2.55-1.45c.74-.42 1.65.12 1.65.97v9.36c0 .85-.91 1.39-1.65.97L16 16.2v.55A2.25 2.25 0 0 1 13.75 19H7.5a2.25 2.25 0 0 1-2.25-2.25v-9.5Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.7" />
        <path d="m9.6 9.1 3.7 2.4-3.7 2.4V9.1Z" fill="currentColor" />
      </svg>
    )
  }
  if (/表格|xlsx|csv|sheet/.test(normalizedKind)) {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M5.5 5.75A2.25 2.25 0 0 1 7.75 3.5h8.5a2.25 2.25 0 0 1 2.25 2.25v12.5a2.25 2.25 0 0 1-2.25 2.25h-8.5a2.25 2.25 0 0 1-2.25-2.25V5.75Z" fill="none" stroke="currentColor" strokeWidth="1.7" />
        <path d="M5.9 9.25h12.2M5.9 13h12.2M10 9.25v10.8" fill="none" stroke="currentColor" strokeLinecap="round" strokeWidth="1.45" />
      </svg>
    )
  }
  return (
    <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
      <path d="M7.25 3.75h6.1L18.75 9v9.25a2 2 0 0 1-2 2h-9.5a2 2 0 0 1-2-2V5.75a2 2 0 0 1 2-2Z" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.7" />
      <path d="M13.2 4.1v3.7c0 .7.56 1.26 1.26 1.26h3.9M8.4 12.5h7.2M8.4 15.8h4.75" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" />
    </svg>
  )
}

function TaskPanelStatCards({ items }: { items: TaskPanelItem[] }) {
  const summary = useMemo(() => summarizeTaskPanelItems(items), [items])
  const stats = [
    { key: "credits", label: "今日消耗Credits", value: summary.creditsUsed.toLocaleString("zh-CN"), icon: "credits" as const },
    { key: "messages", label: "今日消息条数", value: summary.messageCount.toLocaleString("zh-CN"), icon: "messages" as const },
    { key: "artifacts", label: "今日产物数量", value: summary.artifactCount.toLocaleString("zh-CN"), icon: "artifacts" as const },
    { key: "employees", label: "参与员工数量", value: summary.employeeCount.toLocaleString("zh-CN"), icon: "employees" as const }
  ]

  return (
    <section className="task-panel-stats" aria-label="任务统计">
      {stats.map((stat) => (
        <article key={stat.key} className={"task-panel-stat-card task-panel-stat-card-" + stat.key}>
          <span className="task-panel-stat-icon" aria-hidden="true">
            <TaskPanelMetricIcon kind={stat.icon} />
          </span>
          <strong className="task-panel-stat-value">{stat.value}</strong>
          <span className="task-panel-stat-label">{stat.label}</span>
        </article>
      ))}
    </section>
  )
}

function formatTaskPanelOutputTime(task: TaskPanelItem, artifact?: TaskPanelArtifact) {
  const producedAtText = artifact ? artifact.producedAt ?? "" : ""
  if (producedAtText.trim()) {
    return producedAtText.trim()
  }

  const dateText = task.date.replaceAll("-", "/")
  const timeText = task.updatedAt?.trim() ?? "00:00:00"
  const timeMatch = timeText.match(/^(\d{1,2}):(\d{2})(?::(\d{2}))?$/)
  if (!timeMatch) {
    return `${dateText} ${timeText}`
  }

  const hour = timeMatch[1].padStart(2, "0")
  const minute = timeMatch[2]
  const second = timeMatch[3] ?? "00"
  return `${dateText} ${hour}:${minute}:${second}`
}

function getTaskPanelOutputRowKey(task: TaskPanelItem, artifact: TaskPanelArtifact) {
  return `${task.id}:${artifact.id}:${artifact.path ?? artifact.url ?? artifact.name}`
}

function TaskPanelOutputList({ outputs }: { outputs: TaskPanelOutputItem[] }) {
  const [copiedOutputRowKey, setCopiedOutputRowKey] = useState("")
  const copiedTimerRef = useRef<number | null>(null)

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

  useEffect(() => {
    setCopiedOutputRowKey("")
  }, [outputs])

  const copyArtifactUrl = async (outputRowKey: string, artifactUrl: string) => {
    try {
      await navigator.clipboard.writeText(artifactUrl)
      setCopiedOutputRowKey(outputRowKey)
      if (copiedTimerRef.current !== null) {
        window.clearTimeout(copiedTimerRef.current)
      }
      copiedTimerRef.current = window.setTimeout(() => {
        setCopiedOutputRowKey("")
        copiedTimerRef.current = null
      }, 1400)
    } catch {
      // Copy feedback is best-effort and should not affect task data.
    }
  }

  return (
    <section className="task-panel-output-panel" aria-label="内容产出列表">
      <div className="task-panel-output-header">
        <div className="task-panel-output-heading">
          <span className="task-panel-output-heading-icon" aria-hidden="true">
            📦
          </span>
          <h2>内容产出</h2>
        </div>
      </div>
      <div className="task-panel-output-list">
        {outputs.length ? outputs.map(({ artifact, task }) => {
          const artifactPath = artifact.path ?? artifact.url
          const outputRowKey = getTaskPanelOutputRowKey(task, artifact)
          return (
          <article key={outputRowKey} className="task-panel-output-item">
            <span className="task-panel-output-icon" aria-hidden="true">
              <TaskPanelOutputIcon artifact={artifact} />
            </span>
            <div className="task-panel-output-main">
              <div className="task-panel-output-title-row">
                <strong title={artifact.name}>{artifact.name}</strong>
                <span className="task-panel-output-kind">{artifact.kind ?? "产物"}</span>
              </div>
              <p>{artifact.summary ?? task.taskTitle}</p>
              {artifactPath ? (
                <div className="task-panel-output-url-row">
                  <button
                    type="button"
                    className="task-panel-output-url"
                    title={artifactPath}
                    onClick={() => void copyArtifactUrl(outputRowKey, artifactPath)}
                  >
                    {artifactPath}
                  </button>
                  {copiedOutputRowKey === outputRowKey ? (
                    <span className="task-panel-artifact-copied" aria-live="polite">✅已复制</span>
                  ) : null}
                </div>
              ) : null}
            </div>
            <div className="task-panel-output-meta">
              <span className={"task-panel-expert-icon task-panel-expert-icon-" + resolveTaskExpertIconKey(task.expertName)} aria-hidden="true">
                {renderExpertIcon(resolveTaskExpertIconKey(task.expertName))}
              </span>
              <div>
                <strong title={task.expertName}>{task.expertName}</strong>
                <span title={task.taskTitle}>{formatTaskPanelOutputTime(task, artifact)} · {task.taskTitle}</span>
              </div>
            </div>
          </article>
          )
        }) : (
          <div className="empty-state task-panel-state task-panel-output-empty">
            当前日期暂无内容产出
          </div>
        )}
      </div>
    </section>
  )
}

function TaskPanelLoadingState() {
  return (
    <div className="task-panel-loading-state" role="status" aria-label="任务列表加载中">
      {Array.from({ length: 4 }, (_, index) => (
        <div className="task-panel-loading-row" key={index} aria-hidden="true">
          <span className="task-panel-loading-avatar" />
          <span className="task-panel-loading-line task-panel-loading-line-name" />
          <span className="task-panel-loading-line task-panel-loading-line-task" />
          <span className="task-panel-loading-pill" />
          <span className="task-panel-loading-line task-panel-loading-line-artifact" />
        </div>
      ))}
    </div>
  )
}

export function TaskPanelView() {
  const [selectedDate, setSelectedDate] = useState(getDefaultTaskPanelDate)
  const [items, setItems] = useState<TaskPanelItem[]>([])
  const [loading, setLoading] = useState(true)
  const [errorText, setErrorText] = useState("")
  const [greetingText, setGreetingText] = useState("")
  const dateInputRef = useRef<HTMLInputElement | null>(null)

  useEffect(() => {
    const greeting = "Hi，今日任务请查收～"
    let index = 0
    setGreetingText("")

    const timer = window.setInterval(() => {
      index += 1
      setGreetingText(greeting.slice(0, index))
      if (index >= greeting.length) {
        window.clearInterval(timer)
      }
    }, 42)

    return () => {
      window.clearInterval(timer)
    }
  }, [])

  useEffect(() => {
    let active = true
    setLoading(true)
    setErrorText("")

    void loadTaskPanelItems(selectedDate)
      .then((nextItems) => {
        if (active) {
          setItems(nextItems)
        }
      })
      .catch((error: unknown) => {
        if (active) {
          setItems([])
          setErrorText(error instanceof Error ? error.message : "任务列表加载失败")
        }
      })
      .finally(() => {
        if (active) {
          setLoading(false)
        }
      })

    return () => {
      active = false
    }
  }, [selectedDate])

  const displayDate = useMemo(() => selectedDate.replaceAll("-", "/"), [selectedDate])
  const displayMonth = useMemo(() => `${Number(selectedDate.slice(5, 7))}月`, [selectedDate])
  const outputItems = useMemo<TaskPanelOutputItem[]>(() => {
    return items.flatMap((task) => getVisibleTaskPanelArtifacts(task).map((artifact) => ({ artifact, task })))
  }, [items])

  return (
    <div className="page-stack task-panel-page-stack">
      <Panel className="task-panel-page" bodyClassName="task-panel-body">
        <div className="task-panel-header">
          <div className="task-panel-title-group">
            <h1 className="task-panel-heading">任务面板</h1>
            <p className="task-panel-greeting" aria-label="任务面板问候语">{greetingText}</p>
          </div>
          <div className="task-panel-date-field">
            <button
              type="button"
              className="task-panel-date-pill"
              aria-label={"选择日期，当前为 " + displayDate}
              onClick={() => {
                const dateInput = dateInputRef.current
                if (!dateInput) {
                  return
                }
                if (typeof dateInput.showPicker === "function") {
                  dateInput.showPicker()
                } else {
                  dateInput.click()
                }
              }}
            >
              <span className="task-panel-date-calendar" aria-hidden="true">
                <span className="task-panel-date-calendar-month">{displayMonth}</span>
                <span className="task-panel-date-calendar-day">{selectedDate.slice(-2)}</span>
              </span>
              <span className="task-panel-date-value">{displayDate}</span>
            </button>
            <input
              ref={dateInputRef}
              type="date"
              aria-hidden="true"
              tabIndex={-1}
              value={selectedDate}
              onChange={(event) => setSelectedDate(event.currentTarget.value)}
            />
          </div>
        </div>

        <ScrollArea className="scroll-panel task-panel-scroll" aria-busy={loading}>
          {loading ? <TaskPanelLoadingState /> : null}
          {!loading && errorText ? <div className="notice error task-panel-state" role="alert">{errorText}</div> : null}
          {!loading && !errorText && !items.length ? <div className="empty-state task-panel-state">当天暂无任务</div> : null}
          {!loading && !errorText && items.length ? (
            <div className="task-panel-content">
              <TaskPanelStatCards items={items} />
              <TaskPanelOutputList outputs={outputItems} />
            </div>
          ) : null}
        </ScrollArea>
      </Panel>
    </div>
  )
}
