'use client';

import Link from 'next/link';
import { useSearchParams } from 'next/navigation';
import React, { useEffect, useMemo, useState } from 'react';
import { AlertCircle, ArrowRight, Clock3, FolderDown, ListTodo, Loader2, Play, Plus, RefreshCw, Trash2, X } from 'lucide-react';

import { formatTaskRuntimeTime } from '@/components/task-runtime/TaskRuntimeShared';
import { TaskManagementTabs } from '@/components/task-management/TaskManagementTabs';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { addCronJob, deleteBackendTask, listBackendTasks, listCronJobs, removeCronJob, runCronJob, toggleCronJob } from '@/lib/api';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import { useChatStore } from '@/lib/store';
import type { BackendTask, CronJob } from '@/types';

export default function TasksPage() {
  const { locale } = useAppI18n();
  const searchParams = useSearchParams();
  const tab = searchParams.get('tab') === 'scheduled' ? 'scheduled' : 'ordinary';

  return (
    <div className="mx-auto max-w-7xl space-y-6 p-6">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-normal">{pickAppText(locale, '任务', 'Tasks')}</h1>
          <p className="mt-2 max-w-2xl text-sm text-muted-foreground">
            {pickAppText(locale, '普通任务展示用户发起或接入的工作任务；定时任务触发后会先进入通知，需要修改时再接入 Task。', 'Ordinary tasks show user-started or engaged work. Scheduled jobs first create notifications and only become Tasks when revised.')}
          </p>
        </div>
        <TaskManagementTabs />
      </div>

      {tab === 'scheduled' ? <ScheduledTasks /> : <OrdinaryTasks />}
    </div>
  );
}

function OrdinaryTasks() {
  const { locale } = useAppI18n();
  const [backendTasks, setBackendTasks] = useState<BackendTask[]>([]);
  const [error, setError] = useState<string | null>(null);

  const visibleTasks = useMemo(
    () => backendTasks.filter((task) => {
      if (task.creator !== 'cron') return true;
      return Boolean(task.metadata?.user_engaged || task.metadata?.requires_followup);
    }),
    [backendTasks]
  );

  const loadBackendTasks = React.useCallback(() => {
    let cancelled = false;
    listBackendTasks()
      .then((items) => {
        if (!cancelled) setBackendTasks(Array.isArray(items) ? items : []);
      })
      .catch(() => {
        if (!cancelled) setBackendTasks([]);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => loadBackendTasks(), [loadBackendTasks]);

  const handleDeleteBackendTask = async (task: BackendTask) => {
    const title = task.short_title || task.description || task.goal || task.task_id;
    if (!window.confirm(pickAppText(locale, `删除任务“${title}”？`, `Delete task "${title}"?`))) {
      return;
    }
    setError(null);
    try {
      await deleteBackendTask(task.task_id);
      setBackendTasks((items) => items.filter((item) => item.task_id !== task.task_id));
    } catch (err: any) {
      setError(err.message || pickAppText(locale, '删除任务失败', 'Failed to delete task'));
    }
  };

  if (visibleTasks.length === 0) {
    return (
      <Card className="border-dashed">
        <CardContent className="flex flex-col items-center justify-center py-16 text-center">
          <ListTodo className="h-10 w-10 text-muted-foreground/50" />
          <h2 className="mt-4 text-xl font-semibold">{pickAppText(locale, '暂无普通任务', 'No ordinary tasks yet')}</h2>
          <p className="mt-2 max-w-xl text-sm text-muted-foreground">
            {pickAppText(locale, '从对话页发起复杂任务后，这里会保留普通任务列表；即使来源会话被归档，任务仍会显示。', 'Complex tasks created from chat appear here. Tasks remain visible even when their source session is archived.')}
          </p>
          <Button asChild className="mt-6">
            <Link href="/">{pickAppText(locale, '回到对话', 'Back to chat')}</Link>
          </Button>
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-3">
    {error && (
      <Card className="border-destructive">
        <CardContent className="flex items-center gap-2 pt-6 text-sm text-destructive">
          <AlertCircle className="h-4 w-4" />
          {error}
        </CardContent>
      </Card>
    )}
    <Card>
      <CardContent className="p-0">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>{pickAppText(locale, '任务', 'Task')}</TableHead>
              <TableHead>{pickAppText(locale, '状态', 'Status')}</TableHead>
              <TableHead>{pickAppText(locale, '来源', 'Source')}</TableHead>
              <TableHead>{pickAppText(locale, '运行次数', 'Runs')}</TableHead>
              <TableHead>{pickAppText(locale, '使用技能', 'Skills')}</TableHead>
              <TableHead>{pickAppText(locale, '更新时间', 'Updated')}</TableHead>
              <TableHead className="w-24">{pickAppText(locale, '操作', 'Actions')}</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {visibleTasks.map((task) => (
              <TableRow key={task.task_id}>
                <TableCell>
                  <div className="max-w-[360px]">
                    <div className="flex min-w-0 items-center gap-2">
                      <div className="truncate font-medium">{task.short_title || String(task.metadata?.short_title || '') || task.description || task.goal || task.task_id}</div>
                      {task.is_open ? <Badge variant="secondary">{pickAppText(locale, '进行中', 'Active')}</Badge> : null}
                    </div>
                    <div className="mt-1 truncate text-xs text-muted-foreground">
                      {task.description || task.session_id} · {task.creator}
                    </div>
                  </div>
                </TableCell>
                <TableCell>
                  <Badge variant={task.status === 'awaiting_acceptance' || task.status === 'closed' ? 'default' : 'secondary'}>
                    {taskStatusLabel(task.status, locale)}
                  </Badge>
                </TableCell>
                <TableCell>
                  <span className="text-sm text-muted-foreground">{taskSourceLabel(task, locale)}</span>
                </TableCell>
                <TableCell className="text-sm text-muted-foreground">{task.run_ids.length}</TableCell>
                <TableCell className="text-sm text-muted-foreground">{task.skill_names.length}</TableCell>
                <TableCell className="text-xs text-muted-foreground">{formatTaskRuntimeTime(task.updated_at, locale)}</TableCell>
                <TableCell>
                  <div className="flex items-center gap-1">
                    <Button asChild size="sm" variant="outline">
                      <Link href={`/tasks/${encodeURIComponent(task.task_id)}`}>
                        {pickAppText(locale, '进入', 'Open')}
                        <ArrowRight className="ml-2 h-3.5 w-3.5" />
                      </Link>
                    </Button>
                    <Button
                      size="icon"
                      variant="ghost"
                      className="h-8 w-8 text-destructive hover:text-destructive"
                      onClick={() => void handleDeleteBackendTask(task)}
                      title={pickAppText(locale, '删除任务', 'Delete task')}
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </Button>
                  </div>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </CardContent>
    </Card>
    </div>
  );
}

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

function taskSourceLabel(task: BackendTask, locale: 'zh-CN' | 'en-US') {
  if (task.metadata?.source === 'scheduled_run') {
    return pickAppText(locale, '定时通知修改', 'Scheduled notification revision');
  }
  if (task.metadata?.source === 'scheduled_cron') {
    return pickAppText(locale, '定时任务', 'Scheduled task');
  }
  if (task.creator === 'cron') {
    return pickAppText(locale, '定时任务', 'Scheduled task');
  }
  return pickAppText(locale, '对话任务', 'Chat task');
}

function ScheduledTasks() {
  const { locale } = useAppI18n();
  const sessionId = useChatStore((state) => state.sessionId);
  const [jobs, setJobs] = useState<CronJob[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showAdd, setShowAdd] = useState(false);
  const targetSessionKey = sessionId.startsWith('web:') ? sessionId : 'web:default';

  const loadJobs = React.useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      setJobs(await listCronJobs(true));
    } catch (err: any) {
      setError(err.message || pickAppText(locale, '加载定时任务失败', 'Failed to load scheduled tasks'));
    } finally {
      setLoading(false);
    }
  }, [locale]);

  useEffect(() => {
    void loadJobs();
  }, [loadJobs]);

  const formatTime = (ms: number | null) => {
    if (!ms) return '-';
    return new Date(ms).toLocaleString(locale, { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
  };

  const runJobAction = async (action: () => Promise<unknown>) => {
    try {
      await action();
      await loadJobs();
    } catch (err: any) {
      setError(err.message || pickAppText(locale, '操作失败', 'Action failed'));
    }
  };

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-2 text-sm text-muted-foreground">
          <Clock3 className="h-4 w-4" />
          {pickAppText(locale, '每次触发会生成通知记录；需要修改时再接入 Task。', 'Each trigger creates a notification record; connect it to a Task when revision is needed.')}
        </div>
        <div className="flex items-center gap-2">
          <Button onClick={() => void loadJobs()} variant="outline" size="sm">
            <RefreshCw className="mr-2 h-4 w-4" />
            {pickAppText(locale, '刷新', 'Refresh')}
          </Button>
          <Button onClick={() => setShowAdd(true)} size="sm">
            <Plus className="mr-2 h-4 w-4" />
            {pickAppText(locale, '新建定时任务', 'New scheduled task')}
          </Button>
        </div>
      </div>

      {error && (
        <Card className="border-destructive">
          <CardContent className="flex items-center gap-2 pt-6 text-sm text-destructive">
            <AlertCircle className="h-4 w-4" />
            {error}
          </CardContent>
        </Card>
      )}

      {showAdd && (
        <AddJobForm
          targetSessionKey={targetSessionKey}
          onCancel={() => setShowAdd(false)}
          onAdd={(params) =>
            runJobAction(async () => {
              await addCronJob({ ...params, session_key: targetSessionKey, mode: 'notification' });
              setShowAdd(false);
            })
          }
        />
      )}

      <Card>
        <CardContent className="p-0">
          {loading ? (
            <div className="flex items-center justify-center py-16 text-muted-foreground">
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              {pickAppText(locale, '加载中', 'Loading')}
            </div>
          ) : jobs.length === 0 ? (
            <div className="py-14 text-center text-muted-foreground">
              <Clock3 className="mx-auto mb-3 h-10 w-10 opacity-40" />
              <p className="font-medium">{pickAppText(locale, '暂无定时任务', 'No scheduled tasks yet')}</p>
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-16">{pickAppText(locale, '启用', 'Enabled')}</TableHead>
                  <TableHead>{pickAppText(locale, '名称', 'Name')}</TableHead>
                  <TableHead>{pickAppText(locale, '计划', 'Schedule')}</TableHead>
                  <TableHead>{pickAppText(locale, '消息', 'Message')}</TableHead>
                  <TableHead>{pickAppText(locale, '运行历史', 'History')}</TableHead>
                  <TableHead>{pickAppText(locale, '状态', 'Status')}</TableHead>
                  <TableHead className="w-28">{pickAppText(locale, '操作', 'Actions')}</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {jobs.map((job) => (
                  <TableRow key={job.id}>
                    <TableCell>
                      <Switch checked={job.enabled} onCheckedChange={(checked) => void runJobAction(() => toggleCronJob(job.id, checked))} />
                    </TableCell>
                    <TableCell>
                      <div className="font-medium">{job.name}</div>
                      <div className="text-xs text-muted-foreground">{job.id}</div>
                    </TableCell>
                    <TableCell>
                      <code className="rounded bg-muted px-1.5 py-0.5 text-xs">{job.schedule_display}</code>
                      <div className="mt-1 text-xs text-muted-foreground">{pickAppText(locale, '下次', 'Next')}: {formatTime(job.next_run_at_ms)}</div>
                    </TableCell>
                    <TableCell>
                      <span className="block max-w-[260px] truncate text-sm">{job.message}</span>
                    </TableCell>
                    <TableCell>
                      <Button asChild size="sm" variant="outline" disabled={!job.last_scheduled_run_id && !job.last_task_id}>
                        <Link href={job.last_scheduled_run_id ? `/notifications/${encodeURIComponent(job.last_scheduled_run_id)}` : job.last_task_id ? `/tasks/${encodeURIComponent(job.last_task_id)}` : '/tasks'}>
                          <FolderDown className="mr-2 h-3.5 w-3.5" />
                          {formatTime(job.last_run_at_ms)}
                        </Link>
                      </Button>
                    </TableCell>
                    <TableCell>
                      {job.last_status === 'ok' ? (
                        <Badge>{pickAppText(locale, '成功', 'OK')}</Badge>
                      ) : job.last_status === 'error' ? (
                        <Badge variant="destructive">{pickAppText(locale, '错误', 'Error')}</Badge>
                      ) : (
                        <span className="text-xs text-muted-foreground">-</span>
                      )}
                    </TableCell>
                    <TableCell>
                      <div className="flex items-center gap-1">
                        <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => void runJobAction(() => runCronJob(job.id))}>
                          <Play className="h-3.5 w-3.5" />
                        </Button>
                        <Button variant="ghost" size="icon" className="h-8 w-8 text-destructive hover:text-destructive" onClick={() => void runJobAction(() => removeCronJob(job.id))}>
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

function AddJobForm({
  targetSessionKey,
  onAdd,
  onCancel,
}: {
  targetSessionKey: string;
  onAdd: (params: { name: string; message: string; every_seconds?: number; cron_expr?: string; at_iso?: string }) => void;
  onCancel: () => void;
}) {
  const { locale } = useAppI18n();
  const [name, setName] = useState('');
  const [message, setMessage] = useState('');
  const [scheduleType, setScheduleType] = useState<'every' | 'cron' | 'at'>('every');
  const [everySeconds, setEverySeconds] = useState('3600');
  const [cronExpr, setCronExpr] = useState('0 9 * * *');
  const [atIso, setAtIso] = useState('');

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    if (!name.trim() || !message.trim()) return;
    if (scheduleType === 'every') {
      onAdd({ name: name.trim(), message: message.trim(), every_seconds: Number.parseInt(everySeconds, 10) || 3600 });
      return;
    }
    if (scheduleType === 'cron') {
      onAdd({ name: name.trim(), message: message.trim(), cron_expr: cronExpr.trim() });
      return;
    }
    onAdd({ name: name.trim(), message: message.trim(), at_iso: atIso });
  };

  return (
    <Card>
      <CardHeader className="pb-4">
        <div className="flex items-center justify-between">
          <CardTitle className="text-base">{pickAppText(locale, '新建定时任务', 'New scheduled task')}</CardTitle>
          <Button variant="ghost" size="icon" className="h-7 w-7" onClick={onCancel}>
            <X className="h-4 w-4" />
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="grid gap-4 md:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="job-name">{pickAppText(locale, '任务名称', 'Task name')}</Label>
              <Input id="job-name" value={name} onChange={(event) => setName(event.target.value)} />
            </div>
            <div className="space-y-2">
              <Label>{pickAppText(locale, '调度类型', 'Schedule type')}</Label>
              <Select value={scheduleType} onValueChange={(value) => setScheduleType(value as 'every' | 'cron' | 'at')}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="every">{pickAppText(locale, '固定间隔', 'Fixed interval')}</SelectItem>
                  <SelectItem value="cron">Cron</SelectItem>
                  <SelectItem value="at">{pickAppText(locale, '一次性', 'One-time')}</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          {scheduleType === 'every' ? (
            <div className="space-y-2">
              <Label htmlFor="every-seconds">{pickAppText(locale, '间隔秒数', 'Interval seconds')}</Label>
              <Input id="every-seconds" type="number" min="10" value={everySeconds} onChange={(event) => setEverySeconds(event.target.value)} />
            </div>
          ) : scheduleType === 'cron' ? (
            <div className="space-y-2">
              <Label htmlFor="cron-expr">Cron</Label>
              <Input id="cron-expr" value={cronExpr} onChange={(event) => setCronExpr(event.target.value)} />
            </div>
          ) : (
            <div className="space-y-2">
              <Label htmlFor="at-iso">{pickAppText(locale, '触发时间', 'Run at')}</Label>
              <Input id="at-iso" type="datetime-local" value={atIso} onChange={(event) => setAtIso(event.target.value)} />
            </div>
          )}
          <div className="space-y-2">
            <Label htmlFor="job-message">{pickAppText(locale, '任务消息', 'Task message')}</Label>
            <Input id="job-message" value={message} onChange={(event) => setMessage(event.target.value)} />
            <p className="text-xs text-muted-foreground">
              {pickAppText(locale, '触发后会发送到固定通知 session；需要修改时再接入 Task。来源会话：', 'Triggers are sent to the fixed notification session; connect to a Task for revisions. Source session: ')}
              <code className="rounded bg-muted px-1 py-0.5">{targetSessionKey}</code>
            </p>
          </div>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={onCancel}>{pickAppText(locale, '取消', 'Cancel')}</Button>
            <Button type="submit" disabled={!name.trim() || !message.trim()}>
              <Plus className="mr-2 h-4 w-4" />
              {pickAppText(locale, '创建', 'Create')}
            </Button>
          </div>
        </form>
      </CardContent>
    </Card>
  );
}
