'use client';

import { RouteGuard } from '@/components/auth/Guard';
import { useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Search, FolderKanban, Package, ChevronDown, Plus, X, MoreHorizontal, Trash2, Pencil } from 'lucide-react';
import { useProductStore } from '@/stores/useProductStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useVersionPlanStore } from '@/stores/useVersionPlanStore';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useTestCaseStore } from '@/stores/useTestCaseStore';
import { flattenProjects, flattenVersions, ProjectWithContext } from '@/lib/derive';
import { VersionChip } from '@/components/version/VersionChip';
import { Pagination, usePagination } from '@/components/Pagination';
import { buildVersionProgressMap } from '@/lib/version-progress';
import { useHasPermission } from '@/components/auth/Guard';

export default function ProjectsPage() {
  return (
    <RouteGuard permission="project:view">
      <ProjectsPageContent />
    </RouteGuard>
  );
}

function ProjectsPageContent() {
  const router = useRouter();
  const { overview, fetchOverview, createProject, updateProject, deleteProject } = useProductStore();
  const { requirements, fetchRequirements } = useRequirementStore();
  const { plans, fetchPlans } = useVersionPlanStore();
  const { tasks: devTasks, fetchTasks: fetchDevTasks } = useDevTaskStore();
  const { testCases, fetchTestCases } = useTestCaseStore();
  const [search, setSearch] = useState('');
  const [productFilter, setProductFilter] = useState<string>('all');
  const [showForm, setShowForm] = useState(false);
  const [editingProject, setEditingProject] = useState<ProjectWithContext | null>(null);

  useEffect(() => { fetchOverview(); }, [fetchOverview]);
  useEffect(() => { fetchRequirements(); }, [fetchRequirements]);
  useEffect(() => { fetchPlans(); }, [fetchPlans]);
  useEffect(() => { fetchDevTasks(); }, [fetchDevTasks]);
  useEffect(() => { fetchTestCases(); }, [fetchTestCases]);

  const allProjects = useMemo(() => flattenProjects(overview), [overview]);
  const allVersions = useMemo(() => flattenVersions(overview), [overview]);

  const versionProgressMap = useMemo(
    () => buildVersionProgressMap(allVersions, plans, requirements, devTasks, testCases),
    [allVersions, plans, requirements, devTasks, testCases],
  );

  const filtered = useMemo(() => {
    return allProjects.filter((p) => {
      if (productFilter !== 'all' && p.productId !== productFilter) return false;
      if (search && !p.name.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    });
  }, [allProjects, search, productFilter]);

  const { paged, page, setPage, total, pageSize, setPageSize } = usePagination(filtered, 20);

  const productOptions = useMemo(
    () => overview.map((p) => ({ id: p.id, name: p.name })),
    [overview]
  );

  const activeProductName =
    productFilter === 'all'
      ? '全部产品'
      : productOptions.find((p) => p.id === productFilter)?.name || '全部产品';

  return (
    <div className="flex h-full flex-col">
      {/* Header */}
      <header className="flex h-14 shrink-0 items-center justify-between border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
        <div className="flex items-center gap-2.5">
          <h1 className="text-[15px] font-semibold tracking-tight text-[var(--ink)]">项目</h1>
          <span className="rounded-md bg-[var(--bg-subtle)] px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-[var(--ink-soft)]">
            {allProjects.length}
          </span>
        </div>
        <button
          onClick={() => setShowForm(true)}
          className="flex h-8 items-center gap-1.5 rounded-lg bg-[var(--accent)] px-3 text-[13px] font-medium text-white shadow-[var(--shadow-sm)] hover:bg-[var(--accent-hover)]"
        >
          <Plus className="h-3.5 w-3.5" strokeWidth={2.5} />
          新建项目
        </button>
      </header>

      {/* Filters */}
      <div className="flex shrink-0 items-center gap-3 border-b border-[var(--line)] bg-[var(--bg-card)] px-5 py-3">
        <div className="relative flex-1 max-w-sm">
          <Search className="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-[var(--ink-muted)]" />
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="搜索项目名称…"
            className="h-8 w-full rounded-lg border border-[var(--line)] bg-[var(--bg)] pl-8 pr-3 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:border-[var(--accent)] focus:outline-none focus:ring-2 focus:ring-[var(--accent-ring)]"
          />
        </div>

        <ProductDropdown
          value={productFilter}
          options={productOptions}
          onChange={setProductFilter}
          activeName={activeProductName}
        />

        <div className="ml-auto flex items-center gap-3 text-[11px] text-[var(--ink-muted)]">
          <LegendDot color="bg-blue-500" label="开发中" />
          <LegendDot color="bg-orange-500" label="规划中" />
          <LegendDot color="bg-gray-400" label="已发布" />
        </div>
      </div>

      {/* List */}
      <div className="flex-1 overflow-y-auto bg-[var(--bg)] p-5">
        {filtered.length === 0 ? (
          <EmptyState />
        ) : (
          <div>
            <div className="overflow-visible rounded-2xl border border-[var(--line)] bg-[var(--bg-card)] shadow-[var(--shadow-sm)]">
              {paged.map((proj) => (
                <ProjectRow
                  key={proj.id}
                  proj={proj}
                  versionProgressMap={versionProgressMap}
                  onClick={() => router.push(`/projects/${proj.id}`)}
                  onEdit={() => setEditingProject(proj)}
                  onDelete={() => {
                    if (!confirm(`确认删除项目「${proj.name}」？此操作不可恢复。`)) return;
                    deleteProject(proj.productId, proj.id);
                  }}
                />
              ))}
            </div>
            <Pagination total={total} page={page} pageSize={pageSize} onChange={setPage} onPageSizeChange={setPageSize} />
          </div>
        )}
      </div>

      {showForm && (
        <CreateProjectModal
          products={productOptions}
          overview={overview}
          onClose={() => setShowForm(false)}
          onSubmit={async (productId, name, description) => {
            await createProject(productId, { name, description });
            setShowForm(false);
          }}
        />
      )}

      {editingProject && (
        <EditProjectModal
          project={editingProject}
          overview={overview}
          onClose={() => setEditingProject(null)}
          onSubmit={async (name) => {
            updateProject(editingProject.productId, editingProject.id, { name });
            setEditingProject(null);
          }}
        />
      )}
    </div>
  );
}

/* ─── ProjectRow ─────────────────────────────────────────────────── */

function ProjectRow({
  proj,
  versionProgressMap,
  onClick,
  onEdit,
  onDelete,
}: {
  proj: ProjectWithContext;
  versionProgressMap: Record<string, number>;
  onClick: () => void;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const canEdit = useHasPermission('project:edit');
  const canDelete = useHasPermission('project:delete');
  const [menuOpen, setMenuOpen] = useState(false);
  const activeVersions = proj.versions.filter((v) => (versionProgressMap[v.id] ?? 0) < 100);
  const completedCount = proj.versions.filter((v) => (versionProgressMap[v.id] ?? 0) >= 100).length;
  const versionCount = proj.versions.length;
  const canActuallyDelete = versionCount === 0;

  return (
    <div
      onClick={onClick}
      className={`relative w-full flex items-center gap-4 px-5 py-4 text-left transition-colors hover:bg-[var(--bg-hover)] border-b border-[var(--line-soft)] last:border-b-0 cursor-pointer ${menuOpen ? 'z-40' : 'z-0'}`}
    >
      <FolderKanban size={20} className="shrink-0 text-[var(--ink-muted)]" />
      <span className="font-medium text-[var(--ink)] min-w-[120px] shrink-0">
        {proj.name}
      </span>
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--bg-subtle)] text-xs text-[var(--ink-soft)] shrink-0">
        <Package size={12} />
        {proj.productName}
      </span>
      <span className="flex-1 text-sm text-[var(--ink-muted)] truncate">
        {proj.description}
      </span>
      <div className="flex items-center gap-1.5 shrink-0">
        {activeVersions.map((v) => (
          <VersionChip key={v.id} name={v.name} status={v.status} />
        ))}
        {completedCount > 0 && (
          <span className="text-xs text-[var(--ink-muted)] ml-1">
            +{completedCount} 已完成
          </span>
        )}
      </div>
      {(canEdit || canDelete) && (
        <div className="relative shrink-0" onClick={(e) => e.stopPropagation()}>
          <button
            onClick={() => setMenuOpen(!menuOpen)}
            className="p-1.5 rounded-md text-[var(--ink-muted)] hover:bg-[var(--bg-subtle)] hover:text-[var(--ink)]"
            title="更多操作"
          >
            <MoreHorizontal size={16} />
          </button>
          {menuOpen && (
            <>
              <div className="fixed inset-0 z-30" onClick={() => setMenuOpen(false)} />
              <div className="absolute right-0 top-full z-50 mt-1 min-w-[160px] rounded-lg border border-[var(--line)] bg-[var(--bg-card)] py-1 shadow-[var(--shadow-md)]">
                {canEdit && (
                  <button
                    onClick={() => {
                      setMenuOpen(false);
                      onEdit();
                    }}
                    className="w-full flex items-center gap-2 px-3 py-1.5 text-left text-[12px] text-[var(--ink-soft)] transition-colors hover:bg-[var(--bg-hover)]"
                  >
                    <Pencil size={14} />
                    编辑项目
                  </button>
                )}
                {canDelete && (
                  <button
                    onClick={() => {
                      if (!canActuallyDelete) return;
                      setMenuOpen(false);
                      onDelete();
                    }}
                    disabled={!canActuallyDelete}
                    title={canActuallyDelete ? '' : `项目下还有 ${versionCount} 个版本，不可删除`}
                    className={`w-full flex items-center gap-2 px-3 py-1.5 text-left text-[12px] transition-colors ${canActuallyDelete ? 'text-red-600 hover:bg-red-50' : 'text-[var(--ink-muted)] cursor-not-allowed'}`}
                  >
                    <Trash2 size={14} />
                    删除项目
                  </button>
                )}
              </div>
            </>
          )}
        </div>
      )}
    </div>
  );
}

/* ─── ProductDropdown ────────────────────────────────────────────── */

function ProductDropdown({
  value,
  options,
  onChange,
  activeName,
}: {
  value: string;
  options: { id: string; name: string }[];
  onChange: (v: string) => void;
  activeName: string;
}) {
  const [open, setOpen] = useState(false);

  return (
    <div className="relative">
      <button
        type="button"
        onClick={() => setOpen(!open)}
        className={`flex h-8 items-center gap-1.5 rounded-lg border px-3 text-[13px] font-medium transition-colors ${
          value !== 'all'
            ? 'border-[var(--accent)] bg-[var(--accent-soft)] text-[var(--accent)]'
            : 'border-[var(--line)] bg-[var(--bg)] text-[var(--ink-soft)] hover:bg-[var(--bg-hover)]'
        }`}
      >
        {activeName}
        <ChevronDown size={14} />
      </button>
      {open && (
        <>
          <div className="fixed inset-0 z-10" onClick={() => setOpen(false)} />
          <div className="absolute left-0 top-full z-20 mt-1 min-w-[160px] overflow-hidden rounded-xl border border-[var(--line)] bg-[var(--bg-card)] py-1 shadow-[var(--shadow-md)]">
            <DropdownItem
              active={value === 'all'}
              onClick={() => { onChange('all'); setOpen(false); }}
              label="全部产品"
            />
            {options.map((opt) => (
              <DropdownItem
                key={opt.id}
                active={value === opt.id}
                onClick={() => { onChange(opt.id); setOpen(false); }}
                label={opt.name}
              />
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function DropdownItem({
  active,
  onClick,
  label,
}: {
  active: boolean;
  onClick: () => void;
  label: string;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={`block w-full px-3 py-1.5 text-left text-[13px] transition-colors ${
        active
          ? 'bg-[var(--accent-soft)] text-[var(--accent)] font-medium'
          : 'text-[var(--ink-soft)] hover:bg-[var(--bg-hover)]'
      }`}
    >
      {label}
    </button>
  );
}

/* ─── LegendDot ──────────────────────────────────────────────────── */

function LegendDot({ color, label }: { color: string; label: string }) {
  return (
    <span className="inline-flex items-center gap-1.5">
      <span className={`inline-block h-1.5 w-1.5 rounded-full ${color}`} />
      {label}
    </span>
  );
}

/* ─── EmptyState ─────────────────────────────────────────────────── */

function EmptyState() {
  return (
    <div className="flex flex-col items-center justify-center rounded-2xl border border-dashed border-[var(--line)] bg-[var(--bg-card)] py-20 text-center">
      <FolderKanban size={32} className="text-[var(--ink-muted)] mb-3" />
      <p className="text-sm font-medium text-[var(--ink-soft)]">暂无匹配项目</p>
      <p className="mt-1 text-xs text-[var(--ink-muted)]">尝试调整搜索条件或筛选器</p>
    </div>
  );
}

/* ─── EditProjectModal ───────────────────────────────────────────── */

function EditProjectModal({
  project,
  overview,
  onClose,
  onSubmit,
}: {
  project: ProjectWithContext;
  overview: any[];
  onClose: () => void;
  onSubmit: (name: string) => Promise<void>;
}) {
  const [name, setName] = useState(project.name);
  const [submitting, setSubmitting] = useState(false);
  const [duplicateError, setDuplicateError] = useState(false);

  const handleSubmit = async () => {
    const nextName = name.trim();
    if (!nextName) return;

    const product = overview.find((p: any) => p.id === project.productId);
    const exists = product?.projects?.some(
      (proj: any) => proj.id !== project.id && proj.name === nextName,
    );
    if (exists) {
      setDuplicateError(true);
      return;
    }

    setSubmitting(true);
    try {
      await onSubmit(nextName);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
      <div className="w-full max-w-md rounded-2xl bg-[var(--bg-card)] p-6 shadow-[var(--shadow-md)]">
        <div className="mb-5 flex items-center justify-between">
          <h2 className="text-base font-semibold text-[var(--ink)]">编辑项目</h2>
          <button type="button" onClick={onClose} className="text-[var(--ink-muted)] hover:text-[var(--ink)]">
            <X size={18} />
          </button>
        </div>
        <div>
          <label className="mb-1.5 block text-[12px] font-medium text-[var(--ink-soft)]">
            项目名称 <span className="text-red-500">*</span>
          </label>
          <input
            type="text"
            value={name}
            onChange={(e) => { setName(e.target.value); setDuplicateError(false); }}
            className={`h-9 w-full rounded-lg border bg-[var(--bg)] px-3 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:outline-none focus:ring-2 ${
              duplicateError
                ? 'border-red-500 focus:border-red-500 focus:ring-red-100'
                : 'border-[var(--line)] focus:border-[var(--accent)] focus:ring-[var(--accent-ring)]'
            }`}
          />
          {duplicateError && (
            <p className="mt-1 text-[11px] text-red-500">该产品下已存在同名项目</p>
          )}
        </div>

        <div className="mt-6 flex items-center justify-end gap-2">
          <button
            type="button"
            onClick={onClose}
            className="h-8 rounded-lg border border-[var(--line)] bg-[var(--bg)] px-3 text-[13px] font-medium text-[var(--ink-soft)] hover:bg-[var(--bg-hover)]"
          >
            取消
          </button>
          <button
            type="button"
            onClick={handleSubmit}
            disabled={submitting || !name.trim() || name.trim() === project.name}
            className="h-8 rounded-lg bg-[var(--accent)] px-3 text-[13px] font-medium text-white shadow-[var(--shadow-sm)] hover:bg-[var(--accent-hover)] disabled:cursor-not-allowed disabled:opacity-50"
          >
            {submitting ? '保存中…' : '保存'}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ─── CreateProjectModal ─────────────────────────────────────────── */

function CreateProjectModal({
  products,
  overview,
  onClose,
  onSubmit,
}: {
  products: { id: string; name: string }[];
  overview: any[];
  onClose: () => void;
  onSubmit: (productId: string, name: string, description: string) => Promise<void>;
}) {
  const [productId, setProductId] = useState('');
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [duplicateError, setDuplicateError] = useState(false);

  const handleSubmit = async () => {
    if (!productId || !name.trim()) return;

    const product = overview.find((p: any) => p.id === productId);
    if (product) {
      const exists = product.projects?.some(
        (proj: any) => proj.name === name.trim()
      );
      if (exists) {
        setDuplicateError(true);
        return;
      }
    }

    setSubmitting(true);
    try {
      await onSubmit(productId, name.trim(), description.trim());
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
      <div className="w-full max-w-md rounded-2xl bg-[var(--bg-card)] p-6 shadow-[var(--shadow-md)]">
        <div className="flex items-center justify-between mb-5">
          <h2 className="text-base font-semibold text-[var(--ink)]">新建项目</h2>
          <button type="button" onClick={onClose} className="text-[var(--ink-muted)] hover:text-[var(--ink)]">
            <X size={18} />
          </button>
        </div>
        <div className="space-y-4">
          {/* Product select */}
          <div>
            <label className="block text-[12px] font-medium text-[var(--ink-soft)] mb-1.5">
              产品 <span className="text-red-500">*</span>
            </label>
            <div className="relative">
              <select
                value={productId}
                onChange={(e) => setProductId(e.target.value)}
                className="h-9 w-full appearance-none rounded-lg border border-[var(--line)] bg-[var(--bg)] px-3 pr-8 text-[13px] text-[var(--ink)] focus:border-[var(--accent)] focus:outline-none focus:ring-2 focus:ring-[var(--accent-ring)]"
              >
                <option value="">请选择产品</option>
                {products.map((p) => (
                  <option key={p.id} value={p.id}>{p.name}</option>
                ))}
              </select>
              <ChevronDown size={14} className="pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 text-[var(--ink-muted)]" />
            </div>
          </div>

          {/* Name */}
          <div>
            <label className="block text-[12px] font-medium text-[var(--ink-soft)] mb-1.5">
              项目名称 <span className="text-red-500">*</span>
            </label>
            <input
              type="text"
              value={name}
              onChange={(e) => { setName(e.target.value); setDuplicateError(false); }}
              placeholder="请输入项目名称"
              className={`h-9 w-full rounded-lg border bg-[var(--bg)] px-3 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:outline-none focus:ring-2 ${
                duplicateError
                  ? 'border-red-500 focus:border-red-500 focus:ring-red-100'
                  : 'border-[var(--line)] focus:border-[var(--accent)] focus:ring-[var(--accent-ring)]'
              }`}
            />
            {duplicateError && (
              <p className="mt-1 text-[11px] text-red-500">该产品下已存在同名项目</p>
            )}
          </div>

          {/* Description */}
          <div>
            <label className="block text-[12px] font-medium text-[var(--ink-soft)] mb-1.5">
              描述
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="项目描述（可选）"
              rows={3}
              className="w-full resize-none rounded-lg border border-[var(--line)] bg-[var(--bg)] px-3 py-2 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:border-[var(--accent)] focus:outline-none focus:ring-2 focus:ring-[var(--accent-ring)]"
            />
          </div>
        </div>

        <div className="mt-6 flex items-center justify-end gap-2">
          <button
            type="button"
            onClick={onClose}
            className="h-8 rounded-lg border border-[var(--line)] bg-[var(--bg)] px-3 text-[13px] font-medium text-[var(--ink-soft)] hover:bg-[var(--bg-hover)]"
          >
            取消
          </button>
          <button
            type="button"
            onClick={handleSubmit}
            disabled={submitting || !productId || !name.trim()}
            className="h-8 rounded-lg bg-[var(--accent)] px-3 text-[13px] font-medium text-white shadow-[var(--shadow-sm)] hover:bg-[var(--accent-hover)] disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {submitting ? '提交中…' : '创建'}
          </button>
        </div>
      </div>
    </div>
  );
}
