'use client';

import { AlertTriangle, Bot, Download, ExternalLink, FileText, Users } from 'lucide-react';

import { TaskRuntimeStatusBadge, formatTaskRuntimeTime } from '@/components/task-runtime/TaskRuntimeShared';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { getFileUrl } from '@/lib/api';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import type { TaskRuntimeStatus } from '@/lib/task-runtime';
import type { BackendTask, ProcessArtifact, ProcessRun, TaskTimelineCard } from '@/types';

type Props = {
  task: BackendTask;
  runs: ProcessRun[];
  artifacts: ProcessArtifact[];
  cards: TaskTimelineCard[];
};

const ACTIVE_RUN_STATUSES = new Set<ProcessRun['status']>(['queued', 'running', 'waiting']);
const RUNTIME_STATUSES = new Set<string>(['queued', 'running', 'waiting', 'blocked', 'done', 'error', 'cancelled']);

function isRuntimeStatus(status: string): status is TaskRuntimeStatus {
  return RUNTIME_STATUSES.has(status);
}

function humanTaskStatus(status: string, locale: 'zh-CN' | 'en-US') {
  const map: Record<string, [string, string]> = {
    open: ['已创建', 'Open'],
    running: ['执行中', 'Running'],
    awaiting_acceptance: ['等待验收', 'Awaiting acceptance'],
    needs_revision: ['需要修改', 'Needs revision'],
    closed: ['已完成', 'Closed'],
    abandoned: ['已放弃', 'Abandoned'],
  };
  const item = map[status];
  return item ? pickAppText(locale, item[0], item[1]) : status;
}

function toTime(value: string): number {
  const parsed = new Date(value).getTime();
  return Number.isFinite(parsed) ? parsed : 0;
}

function isWarningOrError(card: TaskTimelineCard): boolean {
  const severity = String(card.details?.severity || card.details?.level || '').toLowerCase();
  return card.type === 'error' || card.status === 'error' || severity === 'warning' || severity === 'error';
}

function artifactHref(artifact: ProcessArtifact): string | null {
  if (artifact.url) return artifact.url;
  if (artifact.file_id) return getFileUrl(artifact.file_id);
  return null;
}

function inlineArtifactPayload(artifact: ProcessArtifact): { content: string; filename: string; mimeType: string } | null {
  const baseName = (artifact.title || artifact.artifact_id || 'artifact').replace(/[\\/:*?"<>|]+/g, '-');
  if (artifact.content !== undefined) {
    const isMarkdown = artifact.artifact_type === 'markdown';
    return {
      content: artifact.content,
      filename: `${baseName}.${isMarkdown ? 'md' : 'txt'}`,
      mimeType: isMarkdown ? 'text/markdown;charset=utf-8' : 'text/plain;charset=utf-8',
    };
  }
  if (artifact.data !== undefined) {
    return {
      content: JSON.stringify(artifact.data, null, 2),
      filename: `${baseName}.json`,
      mimeType: 'application/json;charset=utf-8',
    };
  }
  return null;
}

function downloadInlineArtifact(artifact: ProcessArtifact): void {
  const payload = inlineArtifactPayload(artifact);
  if (!payload) return;

  const url = URL.createObjectURL(new Blob([payload.content], { type: payload.mimeType }));
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = payload.filename;
  document.body.appendChild(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

function RunRow({ run }: { run: ProcessRun }) {
  const { locale } = useAppI18n();

  return (
    <div className="rounded-md border border-border bg-muted/20 p-3">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <div className="truncate text-sm font-medium">{run.title || run.actor_name}</div>
          <div className="mt-1 truncate text-xs text-muted-foreground">{run.actor_name}</div>
        </div>
        <TaskRuntimeStatusBadge status={run.status} />
      </div>
      <div className="mt-2 text-xs text-muted-foreground">{formatTaskRuntimeTime(run.started_at, locale)}</div>
      {run.summary ? <p className="mt-2 line-clamp-2 text-xs text-muted-foreground">{run.summary}</p> : null}
    </div>
  );
}

export function TaskSideRail({ task, runs, artifacts, cards }: Props) {
  const { locale } = useAppI18n();
  const activeRuns = runs.filter((run) => ACTIVE_RUN_STATUSES.has(run.status));
  const childRuns = runs.filter((run) => Boolean(run.parent_run_id));
  const latestAlert = cards.filter(isWarningOrError).sort((a, b) => toTime(b.createdAt) - toTime(a.createdAt))[0] ?? null;

  return (
    <aside className="space-y-4">
      <Card className="rounded-md">
        <CardHeader>
          <CardTitle className="text-base">{pickAppText(locale, '任务状态', 'Task status')}</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="flex items-center justify-between gap-3">
            {isRuntimeStatus(task.status) ? (
              <TaskRuntimeStatusBadge status={task.status} />
            ) : (
              <Badge variant="outline" className="text-[11px]">
                {humanTaskStatus(task.status, locale)}
              </Badge>
            )}
            <div className="text-sm text-muted-foreground">
              {pickAppText(locale, '活跃运行', 'Active runs')}: <span className="font-medium text-foreground">{activeRuns.length}</span>
            </div>
          </div>
          <div className="text-xs text-muted-foreground">
            {pickAppText(locale, '更新', 'Updated')}: {formatTaskRuntimeTime(task.updated_at, locale)}
          </div>
        </CardContent>
      </Card>

      <Card className="rounded-md">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Bot className="h-4 w-4 text-muted-foreground" />
            {pickAppText(locale, '运行中', 'Active runs')}
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-2">
          {activeRuns.length === 0 ? (
            <p className="text-sm text-muted-foreground">{pickAppText(locale, '暂无活跃运行', 'No active runs')}</p>
          ) : (
            activeRuns.map((run) => <RunRow key={run.run_id} run={run} />)
          )}
        </CardContent>
      </Card>

      {latestAlert ? (
        <Card className="rounded-md border-destructive/40">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-base">
              <AlertTriangle className="h-4 w-4 text-destructive" />
              {pickAppText(locale, '最新提醒', 'Latest alert')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <div className="text-sm font-medium">{latestAlert.title}</div>
            {latestAlert.summary ? <p className="text-sm text-muted-foreground">{latestAlert.summary}</p> : null}
            <div className="text-xs text-muted-foreground">{formatTaskRuntimeTime(latestAlert.createdAt, locale)}</div>
          </CardContent>
        </Card>
      ) : null}

      <Card className="rounded-md">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Users className="h-4 w-4 text-muted-foreground" />
            {pickAppText(locale, 'Agent Team', 'Agent team')}
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-2">
          {childRuns.length === 0 ? (
            <p className="text-sm text-muted-foreground">{pickAppText(locale, '暂无子运行', 'No child runs')}</p>
          ) : (
            childRuns.map((run) => <RunRow key={run.run_id} run={run} />)
          )}
        </CardContent>
      </Card>

      <Card className="rounded-md">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <FileText className="h-4 w-4 text-muted-foreground" />
            {pickAppText(locale, '产物', 'Artifacts')}
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-2">
          {artifacts.length === 0 ? (
            <p className="text-sm text-muted-foreground">{pickAppText(locale, '暂无产物', 'No artifacts yet')}</p>
          ) : (
            artifacts.map((artifact) => {
              const href = artifactHref(artifact);
              const inlinePayload = inlineArtifactPayload(artifact);
              return (
                <div key={artifact.artifact_id} className="flex items-center justify-between gap-3 rounded-md border border-border bg-muted/20 p-3">
                  <div className="min-w-0">
                    <div className="flex items-center gap-2 text-sm font-medium">
                      <FileText className="h-4 w-4 shrink-0 text-muted-foreground" />
                      <span className="truncate">{artifact.title}</span>
                    </div>
                    <div className="mt-1 text-xs text-muted-foreground">{artifact.artifact_type}</div>
                  </div>
                  {href ? (
                    <Button asChild size="sm" variant="outline" className="shrink-0">
                      <a href={href} target="_blank" rel="noopener noreferrer">
                        {artifact.url ? <ExternalLink className="mr-2 h-3.5 w-3.5" /> : <Download className="mr-2 h-3.5 w-3.5" />}
                        {artifact.url ? pickAppText(locale, '打开', 'Open') : pickAppText(locale, '下载', 'Download')}
                      </a>
                    </Button>
                  ) : inlinePayload ? (
                    <Button size="sm" variant="outline" className="shrink-0" onClick={() => downloadInlineArtifact(artifact)}>
                      <Download className="mr-2 h-3.5 w-3.5" />
                      {pickAppText(locale, '下载', 'Download')}
                    </Button>
                  ) : null}
                </div>
              );
            })
          )}
        </CardContent>
      </Card>
    </aside>
  );
}
