import { useCallback, useEffect, useMemo, useState } from 'react';
import api from '../services/api';
import Modal from '../components/Modal';
import ConfirmDialog from '../components/ConfirmDialog';
import EmptyState from '../components/EmptyState';
import PriorityBadge from '../components/PriorityBadge';
import { CardSkeleton } from '../components/LoadingSkeleton';
import PersianDateInput from '../components/PersianDateInput';
import MultiSelectDropdown from '../components/MultiSelectDropdown';
import toast from 'react-hot-toast';
import { ArrowRight, CalendarDays, CheckCircle, Edit3, Play, Plus, Timer, Trash2, XCircle } from 'lucide-react';
import { formatJalaliDate, isPastDate } from '../utils/date';
import { Link } from 'react-router-dom';

const initialForm = {
  title: '',
  project_id: '',
  start_date: '',
  end_date: '',
  goal: '',
  capacity_hours: '',
  member_ids: [],
  meeting_setup: [],
};

const statusLabels = {
  planning: 'برنامه‌ریزی شده',
  active: 'فعال',
  completed: 'تمام‌شده',
  cancelled: 'لغوشده',
};

const taskStatusLabels = {
  waiting: 'در انتظار',
  todo: 'برای انجام',
  in_progress: 'در حال انجام',
  review: 'نیاز به بررسی',
  done: 'انجام شد',
};

const boardColumns = [
  { key: 'waiting', label: 'در انتظار' },
  { key: 'todo', label: 'برای انجام' },
  { key: 'in_progress', label: 'در حال انجام' },
  { key: 'review', label: 'نیاز به بررسی' },
  { key: 'done', label: 'انجام شد' },
];

export default function Sprints() {
  const [sprints, setSprints] = useState([]);
  const [projects, setProjects] = useState([]);
  const [users, setUsers] = useState([]);
  const [meetingTypes, setMeetingTypes] = useState([]);
  const [loading, setLoading] = useState(true);
  const [filters, setFilters] = useState({ project_id: '', status: '' });
  const [selected, setSelected] = useState(null);
  const [availableTasks, setAvailableTasks] = useState([]);
  const [report, setReport] = useState(null);
  const [activeTab, setActiveTab] = useState('tasks');
  const [showForm, setShowForm] = useState(false);
  const [editing, setEditing] = useState(null);
  const [form, setForm] = useState(initialForm);
  const [saving, setSaving] = useState(false);
  const [sprintFormStep, setSprintFormStep] = useState(0);
  const [meetingScheduleIndex, setMeetingScheduleIndex] = useState(0);
  const [deleting, setDeleting] = useState(null);
  const [ending, setEnding] = useState(null);
  const [endForm, setEndForm] = useState({ incomplete_action: 'backlog', target_sprint_id: '' });
  const [draggedTask, setDraggedTask] = useState(null);
  const [retro, setRetro] = useState({ went_well: '', problems: '', improvements: '' });

  const fetchSprints = useCallback(async () => {
    setLoading(true);
    try {
      const params = { per_page: 100 };
      if (filters.project_id) params.project_id = filters.project_id;
      if (filters.status) params.status = filters.status;
      const { data } = await api.get('/sprints', { params });
      setSprints(data.data || []);
    } catch {
      toast.error('خطا در دریافت Sprintها');
    } finally {
      setLoading(false);
    }
  }, [filters.project_id, filters.status]);

  useEffect(() => { fetchSprints(); }, [fetchSprints]);

  useEffect(() => {
    api.get('/projects', { params: { per_page: 100 } }).then(({ data }) => setProjects(data.data || [])).catch(() => {});
    api.get('/users', { params: { per_page: 200 } }).then(({ data }) => setUsers(data.data || [])).catch(() => {});
    api.get('/meeting-types').then(({ data }) => setMeetingTypes(data.data || [])).catch(() => {});
  }, []);

  const plannedSprints = useMemo(() => (
    sprints.filter((s) => s.status === 'planning' && (!selected || s.project_id === selected.project_id) && s.id !== selected?.id)
  ), [sprints, selected]);

  const openCreate = () => {
    setEditing(null);
    setForm(initialForm);
    setSprintFormStep(0);
    setMeetingScheduleIndex(0);
    setShowForm(true);
  };

  const openEdit = (sprint) => {
    setEditing(sprint);
    setForm({
      title: sprint.title || '',
      project_id: sprint.project_id || '',
      start_date: sprint.start_date || '',
      end_date: sprint.end_date || '',
      goal: sprint.goal || '',
      capacity_hours: sprint.capacity_hours || '',
      member_ids: (sprint.members || []).map((member) => member.id),
      meeting_setup: [],
    });
    setSprintFormStep(0);
    setMeetingScheduleIndex(0);
    setShowForm(true);
  };

  const suggestedMeetingDate = (typeKey) => {
    if (!form.start_date || !form.end_date) return form.start_date || form.end_date || '';
    if (['sprint_review', 'sprint_retrospective'].includes(typeKey)) return form.end_date;
    if (typeKey === 'backlog_refinement') {
      const start = new Date(`${form.start_date}T00:00:00`);
      const end = new Date(`${form.end_date}T00:00:00`);
      return new Date((start.getTime() + end.getTime()) / 2).toISOString().slice(0, 10);
    }
    return form.start_date;
  };

  const toggleMeetingSetup = (type) => {
    const exists = form.meeting_setup.some((item) => item.type_key === type.key);
    if (exists) {
      setForm({ ...form, meeting_setup: form.meeting_setup.filter((item) => item.type_key !== type.key) });
      return;
    }
    setForm({
      ...form,
      meeting_setup: [...form.meeting_setup, {
        type_key: type.key,
        title: type.default_title || type.name,
        date: suggestedMeetingDate(type.key),
        start_time: type.key === 'daily_standup' ? '09:30' : '10:00',
        reminder_minutes: 30,
        recurrence_rule: type.recurrence_rule || null,
      }],
    });
  };

  const updateMeetingSetup = (typeKey, patch) => {
    setForm({ ...form, meeting_setup: form.meeting_setup.map((item) => item.type_key === typeKey ? { ...item, ...patch } : item) });
  };

  const saveSprint = async (e) => {
    e.preventDefault();
    if (!form.title.trim() || !form.project_id || !form.start_date || !form.end_date) {
      toast.error('عنوان، پروژه و تاریخ‌ها الزامی هستند');
      return;
    }
    setSaving(true);
    try {
      const payload = { ...form, member_ids: form.member_ids.map(Number) };
      if (editing) {
        await api.put(`/sprints/${editing.id}`, payload);
        toast.success('Sprint به‌روزرسانی شد');
      } else {
        await api.post('/sprints', payload);
        toast.success('Sprint ایجاد شد');
      }
      setShowForm(false);
      await fetchSprints();
      if (selected) await loadSprint(selected.id);
    } catch (err) {
      toast.error(err.response?.data?.message || 'خطا در ذخیره Sprint');
    } finally {
      setSaving(false);
    }
  };

  const loadSprint = async (id, tab = activeTab) => {
    try {
      const [{ data: sprintRes }, { data: tasksRes }] = await Promise.all([
        api.get(`/sprints/${id}`),
        api.get(`/sprints/${id}/available-tasks`),
      ]);
      setSelected(sprintRes.data);
      setAvailableTasks(tasksRes.data || []);
      setRetro({
        went_well: sprintRes.data.retrospective?.went_well || '',
        problems: sprintRes.data.retrospective?.problems || '',
        improvements: sprintRes.data.retrospective?.improvements || '',
      });
      setActiveTab(tab);
      if (tab === 'report') fetchReport(id);
    } catch {
      toast.error('خطا در دریافت اطلاعات Sprint');
    }
  };

  const fetchReport = async (id = selected?.id) => {
    if (!id) return;
    try {
      const { data } = await api.get(`/sprints/${id}/report`);
      setReport(data.data);
    } catch {
      toast.error('خطا در دریافت گزارش Sprint');
    }
  };

  const deleteSprint = async () => {
    try {
      await api.delete(`/sprints/${deleting.id}`);
      toast.success('Sprint حذف شد');
      setDeleting(null);
      if (selected?.id === deleting.id) setSelected(null);
      fetchSprints();
    } catch {
      toast.error('خطا در حذف Sprint');
    }
  };

  const addTask = async (taskId) => {
    try {
      await api.post(`/sprints/${selected.id}/tasks`, { task_id: taskId });
      toast.success('تسک به Sprint اضافه شد');
      loadSprint(selected.id);
    } catch (err) {
      toast.error(err.response?.data?.message || 'خطا در افزودن تسک');
    }
  };

  const removeTask = async (taskId) => {
    try {
      await api.delete(`/sprints/${selected.id}/tasks/${taskId}`);
      toast.success('تسک از Sprint جدا شد');
      loadSprint(selected.id);
    } catch {
      toast.error('خطا در جدا کردن تسک');
    }
  };

  const startSprint = async () => {
    try {
      await api.post(`/sprints/${selected.id}/start`);
      toast.success('Sprint شروع شد');
      await fetchSprints();
      await loadSprint(selected.id);
    } catch (err) {
      toast.error(err.response?.data?.message || 'خطا در شروع Sprint');
    }
  };

  const cancelSprint = async () => {
    try {
      await api.post(`/sprints/${selected.id}/cancel`);
      toast.success('Sprint لغو شد');
      await fetchSprints();
      await loadSprint(selected.id);
    } catch (err) {
      toast.error(err.response?.data?.message || 'خطا در لغو Sprint');
    }
  };

  const endSprint = async () => {
    try {
      await api.post(`/sprints/${ending.id}/end`, endForm);
      toast.success('Sprint پایان یافت');
      setEnding(null);
      setEndForm({ incomplete_action: 'backlog', target_sprint_id: '' });
      await fetchSprints();
      await loadSprint(ending.id, 'report');
    } catch (err) {
      toast.error(err.response?.data?.message || 'خطا در پایان Sprint');
    }
  };

  const createQuickNextSprint = async () => {
    if (!selected) return;
    try {
      const start = selected.end_date;
      const end = selected.end_date;
      const { data } = await api.post('/sprints', {
        title: `Sprint بعدی ${selected.project?.title || ''}`.trim(),
        project_id: selected.project_id,
        start_date: start,
        end_date: end,
        goal: '',
        member_ids: (selected.members || []).map((member) => member.id),
      });
      await fetchSprints();
      setEndForm({ incomplete_action: 'move_to_next', target_sprint_id: data.data.id });
      toast.success('Sprint بعدی ساخته شد');
    } catch {
      toast.error('خطا در ساخت سریع Sprint بعدی');
    }
  };

  const updateTaskStatus = async (task, status) => {
    if (!selected || task.status === status) return;
    try {
      await api.put(`/sprints/${selected.id}/tasks/${task.id}/status`, { status });
      setSelected((current) => ({
        ...current,
        tasks: current.tasks.map((item) => item.id === task.id ? { ...item, status } : item),
      }));
    } catch {
      toast.error('خطا در تغییر وضعیت تسک');
      loadSprint(selected.id, 'board');
    }
  };

  const dropTask = (status) => {
    if (!draggedTask) return;
    updateTaskStatus(draggedTask, status);
    setDraggedTask(null);
  };

  const saveRetrospective = async () => {
    try {
      await api.put(`/sprints/${selected.id}/retrospective`, retro);
      toast.success('یادداشت پایان Sprint ذخیره شد');
      loadSprint(selected.id, 'retro');
    } catch {
      toast.error('خطا در ذخیره یادداشت');
    }
  };

  const groupedTasks = useMemo(() => {
    const groups = {};
    boardColumns.forEach((column) => { groups[column.key] = []; });
    (selected?.tasks || []).forEach((task) => {
      const key = groups[task.status] ? task.status : 'todo';
      groups[key].push(task);
    });
    return groups;
  }, [selected]);

  const remainingTasks = selected ? Math.max((selected.total_tasks || 0) - (selected.completed_tasks || 0), 0) : 0;

  if (selected) {
    return (
      <div className="page-container">
        <button className="btn btn-secondary btn-sm" onClick={() => { setSelected(null); setReport(null); }} style={{ marginBottom: '1rem' }}>
          <ArrowRight size={16} /> بازگشت به لیست
        </button>

        <div className="card" style={{ marginBottom: '1rem' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: '1rem', alignItems: 'flex-start', flexWrap: 'wrap' }}>
            <div style={{ minWidth: 260 }}>
              <h1 className="page-title" style={{ marginBottom: '0.5rem' }}>{selected.title}</h1>
              <Link className="btn btn-primary btn-sm" to={`/sprints/${selected.id}/workspace`}>ورود به مرکز فرمان Sprint <ArrowRight size={15} /></Link>
              <div style={{ color: 'var(--gray-600)', fontSize: '0.875rem', maxWidth: 720 }}>
                {selected.goal || 'هدف Sprint ثبت نشده است'}
              </div>
              <div style={{ marginTop: '0.75rem', display: 'flex', flexWrap: 'wrap', gap: '0.5rem', fontSize: '0.8125rem', color: 'var(--gray-500)' }}>
                <span>{selected.project?.title || 'بدون پروژه'}</span>
                <span>•</span>
                <span>{formatJalaliDate(selected.start_date)} تا {formatJalaliDate(selected.end_date)}</span>
                <span>•</span>
                <span>{statusLabels[selected.status]}</span>
              </div>
            </div>
            <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
              {selected.status === 'planning' && <button className="btn btn-primary btn-sm" onClick={startSprint}><Play size={16} /> شروع Sprint</button>}
              {selected.status === 'active' && <button className="btn btn-success btn-sm" onClick={() => { setEnding(selected); setEndForm({ incomplete_action: 'backlog', target_sprint_id: '' }); }}><CheckCircle size={16} /> پایان Sprint</button>}
              {['planning', 'active'].includes(selected.status) && <button className="btn btn-danger btn-sm" onClick={cancelSprint}><XCircle size={16} /> لغو Sprint</button>}
              <button className="btn btn-secondary btn-sm" onClick={() => openEdit(selected)}><Edit3 size={16} /> ویرایش</button>
            </div>
          </div>

          <div className="grid grid-4" style={{ marginTop: '1rem', gap: '0.75rem' }}>
            <Metric label="پیشرفت" value={`${selected.progress || 0}%`} />
            <Metric label="کل تسک‌ها" value={selected.total_tasks || 0} />
            <Metric label="انجام‌شده" value={selected.completed_tasks || 0} />
            <Metric label="باقی‌مانده" value={remainingTasks} />
          </div>
          <div className="progress-bar" style={{ marginTop: '1rem' }}>
            <div className="progress-fill" style={{ width: `${selected.progress || 0}%` }} />
          </div>
        </div>

        <div className="tabs">
          {[
            ['tasks', 'تسک‌ها'],
            ['board', 'برد Sprint'],
            ['report', 'گزارش'],
            ['retro', 'یادداشت پایان Sprint'],
          ].map(([key, label]) => (
            <button key={key} className={`tab ${activeTab === key ? 'active' : ''}`} onClick={() => { setActiveTab(key); if (key === 'report') fetchReport(); }}>{label}</button>
          ))}
        </div>

        {activeTab === 'tasks' && (
          <div className="grid grid-2">
            <div className="card">
              <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>تسک‌های Sprint</h3>
              {(selected.tasks || []).length === 0 ? (
                <EmptyState icon={Timer} title="تسکی در Sprint نیست" description="از بک‌لاگ پروژه تسک اضافه کنید." />
              ) : (
                <div style={{ display: 'grid', gap: '0.625rem' }}>
                  {selected.tasks.map((task) => (
                    <TaskMiniCard key={task.id} task={task} action={<button className="btn btn-sm btn-secondary" onClick={() => removeTask(task.id)}>جدا کردن</button>} />
                  ))}
                </div>
              )}
            </div>
            <div className="card">
              <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>افزودن از تسک‌های پروژه</h3>
              {availableTasks.length === 0 ? (
                <EmptyState icon={CheckCircle} title="تسک قابل افزودن وجود ندارد" description="همه تسک‌های مناسب اضافه شده‌اند یا پروژه تسک باز ندارد." />
              ) : (
                <div style={{ display: 'grid', gap: '0.625rem' }}>
                  {availableTasks.map((task) => (
                    <TaskMiniCard key={task.id} task={task} action={<button className="btn btn-sm btn-primary" onClick={() => addTask(task.id)}>افزودن به Sprint</button>} />
                  ))}
                </div>
              )}
            </div>
          </div>
        )}

        {activeTab === 'board' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, minmax(180px, 1fr))', gap: '0.75rem', overflowX: 'auto', paddingBottom: '0.5rem' }}>
            {boardColumns.map((column) => (
              <div key={column.key} onDragOver={(e) => e.preventDefault()} onDrop={() => dropTask(column.key)} style={{ background: 'var(--surface-muted)', borderRadius: 'var(--radius)', padding: '0.75rem', minHeight: 320 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.75rem' }}>
                  <strong style={{ fontSize: '0.875rem' }}>{column.label}</strong>
                  <span className="badge badge-gray">{groupedTasks[column.key]?.length || 0}</span>
                </div>
                <div style={{ display: 'grid', gap: '0.625rem' }}>
                  {(groupedTasks[column.key] || []).map((task) => (
                    <div key={task.id} draggable onDragStart={() => setDraggedTask(task)}>
                      <TaskMiniCard task={task} compact />
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
        )}

        {activeTab === 'report' && (
          <div className="grid grid-2">
            <div className="card">
              <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>خلاصه پیشرفت</h3>
              <div className="grid grid-2" style={{ gap: '0.75rem' }}>
                <Metric label="کل تسک‌ها" value={report?.total_tasks ?? selected.total_tasks ?? 0} />
                <Metric label="انجام‌شده" value={report?.completed_tasks ?? selected.completed_tasks ?? 0} />
                <Metric label="ناتمام" value={report?.incomplete_tasks ?? remainingTasks} />
                <Metric label="درصد تکمیل" value={`${report?.completion_percentage ?? selected.progress ?? 0}%`} />
              </div>
              <div className="progress-bar" style={{ marginTop: '1rem' }}>
                <div className="progress-fill" style={{ width: `${report?.completion_percentage ?? selected.progress ?? 0}%` }} />
              </div>
            </div>
            <div className="card">
              <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>تسک‌های انجام‌شده توسط اعضا</h3>
              {(report?.completed_by_member || []).length === 0 ? (
                <div style={{ color: 'var(--gray-400)', fontSize: '0.875rem' }}>هنوز تسکی تکمیل نشده است.</div>
              ) : (
                report.completed_by_member.map((item) => (
                  <div key={item.name} style={{ display: 'flex', justifyContent: 'space-between', padding: '0.5rem 0', borderBottom: '1px solid var(--gray-100)' }}>
                    <span>{item.name}</span>
                    <strong>{item.completed}</strong>
                  </div>
                ))
              )}
            </div>
            <div className="card" style={{ gridColumn: '1 / -1' }}>
              <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>تسک‌های ناتمام</h3>
              {(report?.unfinished_tasks || []).length === 0 ? (
                <EmptyState icon={CheckCircle} title="تسک ناتمام وجود ندارد" />
              ) : (
                <div style={{ display: 'grid', gap: '0.625rem' }}>
                  {report.unfinished_tasks.map((task) => <TaskMiniCard key={task.id} task={task} />)}
                </div>
              )}
            </div>
          </div>
        )}

        {activeTab === 'retro' && (
          <div className="card" style={{ maxWidth: 900 }}>
            <h3 style={{ fontSize: '1rem', fontWeight: 700, marginBottom: '1rem' }}>یادداشت پایان Sprint</h3>
            <div className="grid grid-3">
              <TextArea label="چه چیزهایی خوب پیش رفت؟" value={retro.went_well} onChange={(value) => setRetro({ ...retro, went_well: value })} />
              <TextArea label="چه مشکلاتی داشتیم؟" value={retro.problems} onChange={(value) => setRetro({ ...retro, problems: value })} />
              <TextArea label="در Sprint بعدی چه چیزی بهتر شود؟" value={retro.improvements} onChange={(value) => setRetro({ ...retro, improvements: value })} />
            </div>
            <button className="btn btn-primary" onClick={saveRetrospective} style={{ marginTop: '1rem' }}>ذخیره یادداشت</button>
          </div>
        )}

        {showForm && renderSprintForm()}
        {ending && renderEndModal()}
      </div>
    );
  }

  return (
    <div className="page-container">
      <div className="page-header">
        <button className="btn btn-primary" onClick={openCreate}><Plus size={16} /> Sprint جدید</button>
      </div>

      <div className="filter-bar">
        <select className="form-select" value={filters.project_id} onChange={(e) => setFilters({ ...filters, project_id: e.target.value })}>
          <option value="">همه پروژه‌ها</option>
          {projects.map((project) => <option key={project.id} value={project.id}>{project.title}</option>)}
        </select>
        <select className="form-select" value={filters.status} onChange={(e) => setFilters({ ...filters, status: e.target.value })}>
          <option value="">همه وضعیت‌ها</option>
          {Object.entries(statusLabels).map(([key, label]) => <option key={key} value={key}>{label}</option>)}
        </select>
      </div>

      {loading ? (
        <div className="grid grid-3">{Array.from({ length: 6 }).map((_, i) => <CardSkeleton key={i} />)}</div>
      ) : sprints.length === 0 ? (
        <EmptyState icon={Timer} title="Sprintی وجود ندارد" description="برای برنامه‌ریزی کوتاه‌مدت پروژه، یک Sprint بسازید." action={<button className="btn btn-primary" onClick={openCreate}>ایجاد Sprint</button>} />
      ) : (
        <div className="grid grid-3">
          {sprints.map((sprint) => (
            <div key={sprint.id} className="card" style={{ cursor: 'pointer' }} onClick={() => loadSprint(sprint.id)}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: '0.75rem', marginBottom: '0.75rem' }}>
                <div>
                  <h3 style={{ fontSize: '1rem', fontWeight: 700, color: 'var(--gray-900)' }}>{sprint.title}</h3>
                  <div style={{ fontSize: '0.8125rem', color: 'var(--gray-500)', marginTop: 4 }}>{sprint.project?.title || 'بدون پروژه'}</div>
                </div>
                <span className={`badge ${sprint.status === 'active' ? 'badge-success' : sprint.status === 'cancelled' ? 'badge-danger' : 'badge-gray'}`}>{statusLabels[sprint.status]}</span>
              </div>
              <div style={{ display: 'grid', gap: '0.5rem', fontSize: '0.8125rem', color: 'var(--gray-600)' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>شروع</span><strong>{formatJalaliDate(sprint.start_date)}</strong></div>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>پایان</span><strong style={{ color: isPastDate(sprint.end_date) && sprint.status === 'active' ? 'var(--danger)' : undefined }}>{formatJalaliDate(sprint.end_date)}</strong></div>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>تسک‌ها</span><strong>{sprint.total_tasks || 0} کل / {sprint.completed_tasks || 0} انجام‌شده</strong></div>
              </div>
              <div className="progress-bar" style={{ marginTop: '0.875rem' }}>
                <div className="progress-fill" style={{ width: `${sprint.progress || 0}%` }} />
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '0.75rem' }}>
                <span style={{ fontSize: '0.8125rem', fontWeight: 700 }}>{sprint.progress || 0}%</span>
                <div style={{ display: 'flex', gap: '0.25rem' }} onClick={(e) => e.stopPropagation()}>
                  <button className="btn btn-sm btn-secondary" onClick={() => openEdit(sprint)}><Edit3 size={14} /></button>
                  <button className="btn btn-sm btn-danger" onClick={() => setDeleting(sprint)}><Trash2 size={14} /></button>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {showForm && renderSprintForm()}
      {deleting && <ConfirmDialog title="حذف Sprint" message={`آیا از حذف «${deleting.title}» مطمئن هستید؟`} onConfirm={deleteSprint} onCancel={() => setDeleting(null)} danger confirmText="حذف" />}
    </div>
  );

  function renderSprintForm() {
    return (
      <Modal title={editing ? 'ویرایش Sprint' : 'Sprint جدید'} onClose={() => setShowForm(false)} size="xl" footer={
        !editing && sprintFormStep < 2 ? (
          <>
            <button className="btn btn-secondary" onClick={() => setShowForm(false)}>انصراف</button>
            {sprintFormStep > 0 && <button className="btn btn-secondary" onClick={() => setSprintFormStep((step) => step - 1)}>مرحله قبل</button>}
            <button className="btn btn-primary" onClick={() => setSprintFormStep((step) => step + 1)}>{sprintFormStep === 0 ? 'مرحله بعد: جلسات' : 'مرحله بعد: زمان‌بندی'}</button>
          </>
        ) : (
          <>
            {!editing && <button className="btn btn-secondary" onClick={() => setSprintFormStep((step) => Math.max(0, step - 1))}>مرحله قبل</button>}
            <button className="btn btn-primary" onClick={saveSprint} disabled={saving}>{saving ? 'در حال ذخیره...' : 'ذخیره'}</button>
          </>
        )
      }>
        <form onSubmit={saveSprint} className="compact-modal-form">
          {!editing && (
            <div className="modal-wizard-steps" role="tablist" aria-label="مراحل ساخت Sprint">
              <button type="button" role="tab" aria-selected={sprintFormStep === 0} className={sprintFormStep === 0 ? 'active' : 'complete'} onClick={() => setSprintFormStep(0)}><span>{sprintFormStep > 0 ? <CheckCircle size={16} /> : '۱'}</span>اطلاعات Sprint</button>
              <button type="button" role="tab" aria-selected={sprintFormStep === 1} className={sprintFormStep === 1 ? 'active' : sprintFormStep > 1 ? 'complete' : ''} onClick={() => setSprintFormStep(1)}><span>{sprintFormStep > 1 ? <CheckCircle size={16} /> : '۲'}</span>جلسات Sprint</button>
              <button type="button" role="tab" aria-selected={sprintFormStep === 2} className={sprintFormStep === 2 ? 'active' : ''} onClick={() => setSprintFormStep(2)}><span>۳</span>زمان‌بندی</button>
            </div>
          )}
          {(editing || sprintFormStep === 0) && <div className="compact-modal-grid modal-wizard-panel">
            <Field label="عنوان Sprint" required><input className="form-input" value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} /></Field>
            <Field label="پروژه مرتبط" required>
              <select className="form-select" value={form.project_id} onChange={(e) => setForm({ ...form, project_id: e.target.value })}>
                <option value="">انتخاب پروژه</option>
                {projects.map((project) => <option key={project.id} value={project.id}>{project.title}</option>)}
              </select>
            </Field>
            <Field label="تاریخ شروع" required><PersianDateInput value={form.start_date} onChange={(value) => setForm({ ...form, start_date: value })} /></Field>
            <Field label="تاریخ پایان" required><PersianDateInput value={form.end_date} onChange={(value) => setForm({ ...form, end_date: value })} /></Field>
            <Field label="ظرفیت اختیاری (ساعت)"><input className="form-input" type="number" min="0" value={form.capacity_hours} onChange={(e) => setForm({ ...form, capacity_hours: e.target.value })} /></Field>
            <Field label="اعضای Sprint">
              <MultiSelectDropdown
                options={users.map((user) => ({ value: user.id, label: user.name }))}
                value={form.member_ids}
                onChange={(memberIds) => setForm({ ...form, member_ids: memberIds })}
                placeholder="انتخاب اعضای Sprint"
              />
            </Field>
            <Field label="هدف Sprint" className="wide">
              <textarea className="form-textarea" value={form.goal} onChange={(e) => setForm({ ...form, goal: e.target.value })} placeholder="تا پایان این Sprint، نسخه اولیه پنل کاربر آماده تست داخلی شود." />
            </Field>
          </div>}
          {!editing && sprintFormStep === 1 && (
            <section className="sprint-meeting-setup">
              <div className="sprint-meeting-setup-head">
                <div><CalendarDays size={18} /><span><strong>راه‌اندازی جلسات Sprint</strong><small>جلسات استاندارد را انتخاب کنید؛ زمان پیشنهادی قابل ویرایش است.</small></span></div>
                {form.meeting_setup.length === 0 && <span className="badge badge-gray">بدون جلسه</span>}
              </div>
              <div className="sprint-meeting-type-grid">
                {meetingTypes.map((type) => {
                  const checked = form.meeting_setup.some((item) => item.type_key === type.key);
                  return <button type="button" key={type.id} className={checked ? 'active' : ''} onClick={() => toggleMeetingSetup(type)}><span>{checked ? <CheckCircle size={16} /> : <Plus size={16} />}</span><div><strong>{type.name}</strong><small>{type.suggested_duration ? `${type.suggested_duration} دقیقه` : 'مدت آزاد'}</small></div></button>;
                })}
              </div>
            </section>
          )}
          {!editing && sprintFormStep === 2 && (
            <section className="sprint-meeting-setup sprint-schedule-step">
              <div className="sprint-meeting-setup-head">
                <div><CalendarDays size={18} /><span><strong>زمان‌بندی جلسات</strong><small>هر جلسه را جداگانه تنظیم کنید.</small></span></div>
                <span className="badge badge-gray">{form.meeting_setup.length} جلسه</span>
              </div>
              {form.meeting_setup.length > 0 ? (
                <>
                  <div className="sprint-meeting-schedule">
                    {form.meeting_setup.slice(Math.min(meetingScheduleIndex, form.meeting_setup.length - 1), Math.min(meetingScheduleIndex, form.meeting_setup.length - 1) + 1).map((item) => (
                    <div key={item.type_key}>
                      <strong>{meetingTypes.find((type) => type.key === item.type_key)?.name || item.title}</strong>
                      <PersianDateInput value={item.date} onChange={(value) => updateMeetingSetup(item.type_key, { date: value })} />
                      <input className="form-input" type="time" value={item.start_time || ''} onChange={(event) => updateMeetingSetup(item.type_key, { start_time: event.target.value })} />
                      <input className="form-input" type="number" min="0" max="10080" value={item.reminder_minutes ?? 30} onChange={(event) => updateMeetingSetup(item.type_key, { reminder_minutes: Number(event.target.value) })} aria-label="یادآوری به دقیقه" />
                    </div>
                    ))}
                  </div>
                  <div className="schedule-wizard-navigation">
                    <button type="button" className="btn btn-secondary btn-sm" disabled={meetingScheduleIndex === 0} onClick={() => setMeetingScheduleIndex((index) => Math.max(0, index - 1))}>جلسه قبلی</button>
                    <span>{Math.min(meetingScheduleIndex + 1, form.meeting_setup.length)} از {form.meeting_setup.length}</span>
                    <button type="button" className="btn btn-secondary btn-sm" disabled={meetingScheduleIndex >= form.meeting_setup.length - 1} onClick={() => setMeetingScheduleIndex((index) => Math.min(form.meeting_setup.length - 1, index + 1))}>جلسه بعدی</button>
                  </div>
                </>
              ) : <div className="wizard-empty-state">جلسه‌ای انتخاب نشده است؛ می‌توانید Sprint را بدون جلسه ذخیره کنید.</div>}
            </section>
          )}
        </form>
      </Modal>
    );
  }

  function renderEndModal() {
    return (
      <Modal title="پایان Sprint" onClose={() => setEnding(null)} footer={
        <>
          <button className="btn btn-secondary" onClick={() => setEnding(null)}>انصراف</button>
          <button className="btn btn-success" onClick={endSprint}>پایان Sprint</button>
        </>
      }>
        <p style={{ fontSize: '0.875rem', color: 'var(--gray-600)', marginBottom: '1rem' }}>با تسک‌های ناتمام چه کاری انجام شود؟</p>
        <div style={{ display: 'grid', gap: '0.75rem' }}>
          <label><input type="radio" checked={endForm.incomplete_action === 'backlog'} onChange={() => setEndForm({ incomplete_action: 'backlog', target_sprint_id: '' })} /> بازگشت به Backlog</label>
          <label><input type="radio" checked={endForm.incomplete_action === 'keep'} onChange={() => setEndForm({ incomplete_action: 'keep', target_sprint_id: '' })} /> باقی بماند بدون Sprint</label>
          <label><input type="radio" checked={endForm.incomplete_action === 'move_to_next'} onChange={() => setEndForm({ ...endForm, incomplete_action: 'move_to_next' })} /> انتقال به Sprint بعدی</label>
          {endForm.incomplete_action === 'move_to_next' && (
            <div style={{ display: 'flex', gap: '0.5rem' }}>
              <select className="form-select" value={endForm.target_sprint_id} onChange={(e) => setEndForm({ ...endForm, target_sprint_id: e.target.value })}>
                <option value="">انتخاب Sprint برنامه‌ریزی شده</option>
                {plannedSprints.map((sprint) => <option key={sprint.id} value={sprint.id}>{sprint.title}</option>)}
              </select>
              <button className="btn btn-secondary btn-sm" onClick={createQuickNextSprint}>ساخت سریع</button>
            </div>
          )}
        </div>
      </Modal>
    );
  }
}

function Field({ label, required, children, className = '' }) {
  return <div className={`form-group${className ? ` ${className}` : ''}`}><label className="form-label">{label}{required ? ' *' : ''}</label>{children}</div>;
}

function Metric({ label, value }) {
  return <div style={{ background: 'var(--surface-muted)', borderRadius: 'var(--radius-sm)', padding: '0.75rem' }}><div style={{ fontSize: '0.75rem', color: 'var(--gray-500)' }}>{label}</div><div style={{ fontSize: '1.25rem', fontWeight: 800, color: 'var(--gray-900)' }}>{value}</div></div>;
}

function TaskMiniCard({ task, action, compact = false }) {
  return (
    <div style={{ background: 'var(--surface)', border: '1px solid var(--gray-200)', borderRadius: 'var(--radius-sm)', padding: compact ? '0.625rem' : '0.75rem', boxShadow: 'var(--shadow)' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: '0.75rem', alignItems: 'flex-start' }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: '0.875rem', fontWeight: 700, color: 'var(--gray-900)', marginBottom: '0.375rem' }}>{task.title}</div>
          <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', fontSize: '0.75rem', color: 'var(--gray-500)' }}>
            <span>{task.assignee?.name || 'بدون مسئول'}</span>
            <span>{taskStatusLabels[task.status] || task.status || '—'}</span>
            {task.estimated_time && <span>{task.estimated_time} ساعت</span>}
          </div>
        </div>
        <PriorityBadge priority={task.priority} />
      </div>
      {action && <div style={{ marginTop: '0.625rem' }}>{action}</div>}
    </div>
  );
}

function TextArea({ label, value, onChange }) {
  return <Field label={label}><textarea className="form-textarea" value={value} onChange={(e) => onChange(e.target.value)} /></Field>;
}
