'use client';

import { useState } from 'react';
import { FilterSelect } from '@/components/FilterSelect';
import { formatDateTime } from '@/lib/format';
import type { Requirement } from '@/lib/requirement';
import type { RequirementCoverageStatus, VersionPlan, VersionPlanLog, VersionPlanLogView } from '@/lib/version-plan';
import {
  canSaveRequirementCoverageDraft,
  canOpenRequirementCoverageRecord,
  getRequirementCoverage,
  getRequirementCoverageStatus,
  getRequirementCoverageSummary,
  REQUIREMENT_COVERAGE_LABEL,
  updateRequirementCoverage,
} from '@/lib/version-plan';

type RequirementOption = Pick<Requirement, 'id' | 'code' | 'title'> & { isHistorical?: boolean };

interface CoverageProps {
  plan: VersionPlan;
  requirements: RequirementOption[];
  canEdit: boolean;
  currentUserName: string;
  onUpdate: (id: string, data: Partial<VersionPlan>) => void;
}

interface LogTimelineProps {
  logs?: Array<VersionPlanLog | VersionPlanLogView>;
  className?: string;
  fillHeight?: boolean;
}

const COVERAGE_BADGE_STYLE: Record<RequirementCoverageStatus, string> = {
  not_started: 'border-zinc-200 bg-zinc-50 text-zinc-500',
  partial: 'border-amber-200 bg-amber-50 text-amber-700',
  completed: 'border-emerald-200 bg-emerald-50 text-emerald-700',
};

function getLogTone(log: VersionPlanLog): { badge: string } {
  if (log.aiStatus === 'error') {
    return {
      badge: 'border-red-200 bg-red-50 text-red-700',
    };
  }
  if (log.type === 'ai_decompose') {
    return {
      badge: 'border-violet-200 bg-violet-50 text-violet-700',
    };
  }
  if (log.coverageStatus === 'completed') {
    return {
      badge: 'border-emerald-200 bg-emerald-50 text-emerald-700',
    };
  }
  if (log.coverageStatus === 'partial') {
    return {
      badge: 'border-amber-200 bg-amber-50 text-amber-700',
    };
  }
  return {
    badge: 'border-zinc-200 bg-zinc-50 text-zinc-600',
  };
}

function getLogTypeLabel(log: VersionPlanLog): string {
  if (log.type === 'ai_decompose') return 'AI 拆解';
  if (log.type === 'requirement_progress') return '需求进度';
  return '系统记录';
}

function getLogMonthKey(createdAt: string): string | null {
  const date = new Date(createdAt);
  if (Number.isNaN(date.getTime())) return null;
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
}

function getLogMonthLabel(monthKey: string): string {
  const [year, month] = monthKey.split('-');
  return `${year}年${month}月`;
}

export function PlanRequirementCoveragePanel({ plan, requirements, canEdit, currentUserName, onUpdate }: CoverageProps) {
  const [editingRequirementId, setEditingRequirementId] = useState<string | null>(null);
  const [completedContent, setCompletedContent] = useState('');
  const [remainingContent, setRemainingContent] = useState('');
  const summary = getRequirementCoverageSummary(plan);

  if (requirements.length === 0) return null;

  const openEditor = (req: RequirementOption) => {
    const coverage = getRequirementCoverage(plan, req.id);
    setEditingRequirementId(req.id);
    setCompletedContent(coverage?.completedContent ?? '');
    setRemainingContent(coverage?.remainingContent ?? '');
  };

  const closeEditor = () => {
    setEditingRequirementId(null);
    setCompletedContent('');
    setRemainingContent('');
  };

  const canSavePartial = canSaveRequirementCoverageDraft('partial', completedContent, remainingContent);

  const saveCoverage = (req: RequirementOption, status: Extract<RequirementCoverageStatus, 'partial' | 'completed'>) => {
    if (!canEdit || !canSaveRequirementCoverageDraft(status, completedContent, remainingContent)) return;
    const patch = updateRequirementCoverage(plan, {
      requirementId: req.id,
      status,
      completedContent: status === 'partial' ? completedContent : undefined,
      remainingContent: status === 'partial' ? remainingContent : undefined,
      updatedBy: currentUserName,
      requirementCode: req.code,
      requirementTitle: req.title,
    });
    onUpdate(plan.id, patch);
    closeEditor();
  };

  return (
    <div className="mt-3 space-y-2">
      <div className="flex items-center justify-between gap-3">
        <div>
          <div className="text-[11px] font-semibold text-[var(--ink-muted)]">引用需求</div>
          <div className="mt-0.5 text-[11px] text-[var(--ink-soft)]">
            完全完成 {summary.completed} / {summary.total}
            {summary.partial > 0 && <span className="ml-2 text-amber-700">部分完成 {summary.partial}</span>}
          </div>
        </div>
        <span className="shrink-0 text-[11px] font-medium tabular-nums text-[var(--ink-soft)]">{summary.percent}%</span>
      </div>
      <div className="flex items-center gap-2">
        <div className="h-1.5 flex-1 overflow-hidden rounded-full bg-[var(--bg-subtle)]">
          <div className="h-full rounded-full bg-[var(--accent)] transition-all" style={{ width: `${summary.percent}%` }} />
        </div>
      </div>
      <div className="space-y-1 rounded-lg bg-[var(--bg-subtle)] p-2 pr-1">
        {requirements.map((req) => {
          const status = getRequirementCoverageStatus(plan, req.id);
          const coverage = getRequirementCoverage(plan, req.id);
          const isEditing = editingRequirementId === req.id;
          const canOpenRecord = canOpenRequirementCoverageRecord(status, canEdit);
          return (
            <div key={req.id} className="rounded-md px-2 py-1.5 hover:bg-[var(--bg-card)]">
              <div className="flex min-w-0 items-start gap-2">
                <span className={`mt-0.5 inline-flex shrink-0 items-center rounded-md border px-1.5 py-0.5 text-[10px] font-medium ${COVERAGE_BADGE_STYLE[status]}`}>
                  {REQUIREMENT_COVERAGE_LABEL[status]}
                </span>
                <div className="min-w-0 flex-1">
                  <div className="flex min-w-0 items-center gap-2">
                    <span className="shrink-0 font-mono text-[11px] text-[var(--ink-muted)]">{req.code}</span>
                    <span className="min-w-0 truncate text-[12px] font-medium text-[var(--ink)]" title={req.title}>{req.title}</span>
                    {req.isHistorical && <span className="shrink-0 rounded bg-orange-50 px-1.5 py-0.5 text-[10px] text-orange-600">历史</span>}
                  </div>
                  {(coverage?.completedContent || coverage?.remainingContent) && (
                    <div className="mt-1 space-y-0.5 text-[11px] leading-4 text-[var(--ink-soft)]">
                      {coverage.completedContent && <div className="line-clamp-2">已完成：{coverage.completedContent}</div>}
                      {coverage.remainingContent && <div className="line-clamp-2 text-amber-700">剩余：{coverage.remainingContent}</div>}
                    </div>
                  )}
                </div>
                {canEdit && (canOpenRecord || isEditing) && (
                  <div className="flex shrink-0 items-center gap-1.5">
                    <button
                      type="button"
                      onClick={() => isEditing ? closeEditor() : openEditor(req)}
                      className="rounded-md border border-[var(--line)] px-2 py-1 text-[11px] font-medium text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]"
                    >
                      {isEditing ? '收起' : '记录'}
                    </button>
                  </div>
                )}
              </div>
              {isEditing && (
                <div className="mt-2 space-y-2 rounded-lg border border-[var(--line)] bg-[var(--bg-card)] p-2">
                  <textarea
                    value={completedContent}
                    onChange={(e) => setCompletedContent(e.target.value)}
                    rows={2}
                    placeholder="本次已完成的内容"
                    className="w-full resize-none rounded-lg border border-[var(--line)] bg-[var(--bg-card)] px-2 py-1.5 text-[12px] focus:border-[var(--accent)] focus:outline-none"
                  />
                  <textarea
                    value={remainingContent}
                    onChange={(e) => setRemainingContent(e.target.value)}
                    rows={2}
                    placeholder="剩余未完成的内容"
                    className="w-full resize-none rounded-lg border border-[var(--line)] bg-[var(--bg-card)] px-2 py-1.5 text-[12px] focus:border-[var(--accent)] focus:outline-none"
                  />
                  <div className="flex flex-wrap items-center gap-2">
                    <button
                      type="button"
                      onClick={() => saveCoverage(req, 'completed')}
                      className="h-7 rounded-md bg-emerald-600 px-3 text-[11px] font-medium text-white hover:bg-emerald-700"
                    >
                      完全完成
                    </button>
                    <div className="ml-auto flex gap-2">
                      <button
                        type="button"
                        onClick={closeEditor}
                        className="h-7 rounded-md border border-[var(--line)] px-2 text-[11px] font-medium text-[var(--ink-muted)] hover:bg-[var(--bg-subtle)]"
                      >
                        取消
                      </button>
                      <button
                        type="button"
                        onClick={() => saveCoverage(req, 'partial')}
                        disabled={!canSavePartial}
                        className="h-7 rounded-md bg-[var(--accent)] px-3 text-[11px] font-medium text-white hover:bg-[var(--accent-hover)] disabled:opacity-50"
                      >
                        保存记录
                      </button>
                    </div>
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

export function PlanLogTimeline({ logs, className = '', fillHeight = false }: LogTimelineProps) {
  const [selectedMonth, setSelectedMonth] = useState('all');
  const sortedLogs = [...(logs ?? [])].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  const monthOptions = Array.from(new Set(sortedLogs.map((log) => getLogMonthKey(log.createdAt)).filter(Boolean) as string[]))
    .sort((a, b) => b.localeCompare(a));
  const effectiveMonth = selectedMonth === 'all' || monthOptions.includes(selectedMonth) ? selectedMonth : 'all';
  const visibleLogs = effectiveMonth === 'all'
    ? sortedLogs
    : sortedLogs.filter((log) => getLogMonthKey(log.createdAt) === effectiveMonth);
  const frameClass = className || 'border-l border-[var(--line)] pl-4';
  const listClass = fillHeight
    ? 'mt-3 min-h-0 flex-1 overflow-y-auto pr-1'
    : 'mt-3 max-h-80 overflow-y-auto pr-1';

  return (
    <aside className={frameClass}>
      <div className="shrink-0 border-b border-[var(--line)] pb-3">
        <div className="flex items-center justify-between gap-3">
          <div>
            <div className="text-[13px] font-semibold text-[var(--ink)]">日志</div>
            <div className="mt-0.5 text-[11px] text-[var(--ink-muted)]">计划行为与 AI 操作记录</div>
          </div>
          <FilterSelect
            value={effectiveMonth}
            onChange={setSelectedMonth}
            options={monthOptions.map((month) => ({ value: month, label: getLogMonthLabel(month) }))}
            allLabel="全部月份"
          />
        </div>
      </div>
      {visibleLogs.length === 0 ? (
        <div className="mt-4 rounded-lg border border-dashed border-[var(--line)] bg-[var(--bg-subtle)] px-3 py-8 text-center text-[12px] text-[var(--ink-muted)]">
          暂无日志
        </div>
      ) : (
        <div className={listClass}>
          <div>
            {visibleLogs.map((log) => {
              const tone = getLogTone(log);
              return (
                <div key={log.id} className="border-b border-[var(--line)] py-3 first:pt-0 last:border-b-0 last:pb-0">
                  <div className="min-w-0">
                    <div className="flex items-start justify-between gap-3">
                      <div className="flex min-w-0 flex-wrap items-center gap-2">
                        <span className={`inline-flex rounded-md border px-1.5 py-0.5 text-[10px] font-semibold ${tone.badge}`}>
                          {getLogTypeLabel(log)}
                        </span>
                        <span className="min-w-0 truncate text-[11px] text-[var(--ink-muted)]">{log.actor}</span>
                      </div>
                      <span className="shrink-0 text-[10px] tabular-nums text-[var(--ink-muted)]">{formatDateTime(log.createdAt)}</span>
                    </div>
                    <div className="mt-1.5 text-[12px] font-semibold leading-5 text-[var(--ink)]">{log.title}</div>
                    {'planTitle' in log && log.planTitle && (
                      <div className="mt-1 truncate text-[11px] text-[var(--ink-soft)]" title={log.planTitle}>
                        {log.planTitle}
                      </div>
                    )}
                    {log.detail && (
                      <div className="mt-2 border-l-2 border-[var(--line)] bg-[var(--bg-subtle)] px-2.5 py-2 text-[11px] leading-5 text-[var(--ink-soft)]">
                        <div className="whitespace-pre-wrap">{log.detail}</div>
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </aside>
  );
}
