const CREATE_PROJECT_STEPS = [
  { id: 1, title: "Project Basics & Site Location" },
  { id: 2, title: "Work Types & Project Structure" },
  { id: 3, title: "Assign Team" },
  { id: 4, title: "Review & Confirm" }
];

const DEFAULT_TYPES_OF_WORK = [
  "Site Preparation & Earthwork",
  "Foundation Work",
  "Plinth",
  "Piling",
  "RCC Structure",
  "Masonry",
  "Plastering",
  "Waterproofing",
  "Electrical Work",
  "Plumbing Work",
  "Flooring",
  "Doors & Windows",
  "Painting",
  "External Work",
  "Final Inspection & Handover"
];

function CreateProject({ snapshot, onNav }) {
  const activeProject = snapshot.project;
  const activeProjects = snapshot.projects.filter((project) => project.status !== "archived");
  const users = snapshot.users || [];
  const [mode, setMode] = React.useState("create");
  const [step, setStep] = React.useState(1);
  const [form, setForm] = React.useState(() => newProjectForm(activeProject, users));

  React.useEffect(() => {
    if (mode === "edit") setForm(projectToForm(activeProject, users));
  }, [activeProject.id, mode]);

  const update = (key, value) => setForm((current) => ({ ...current, [key]: value }));
  const updateNested = (group, key, value) => setForm((current) => ({ ...current, [group]: { ...current[group], [key]: value } }));
  const updateBlock = (id, key, value) => setForm((current) => ({
    ...current,
    blocks: current.blocks.map((block) => block.id === id ? { ...block, [key]: value } : block)
  }));

  const resetCreate = () => {
    setMode("create");
    setStep(1);
    setForm(newProjectForm(activeProject, users));
  };

  const editActive = () => {
    setMode("edit");
    setStep(1);
    setForm(projectToForm(activeProject, users));
  };

  const addBlock = () => setForm((current) => {
    const block = createBlock(current.blocks.length + 1);
    const schedule = { projectStart: current.startDate || "", projectEnd: current.endDate || "" };
    return {
      ...current,
      blocks: window.WorkPlanEditor.syncPresetTasksForAllBlocks(
        [...current.blocks, block],
        current.typesOfWork,
        current.presetDefaults,
        schedule
      )
    };
  });

  const removeBlock = (id) => setForm((current) => {
    const nextBlocks = current.blocks.filter((block) => block.id !== id);
    return { ...current, blocks: nextBlocks.length ? nextBlocks : [createBlock(1)] };
  });

  const importTasks = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    const rows = await parseTaskFile(file);
    if (!rows.length) {
      window.ConstructProData.showToast("No task rows found. Use task_name, block_name, target_days, estimated_budget.");
      return;
    }
    setForm((current) => ({
      ...current,
      blocks: window.WorkPlanEditor.mergeImportedTasksIntoBlocks(current.blocks, rows)
    }));
    window.ConstructProData.showToast(`${rows.length} task rows imported into blocks.`);
  };

  const setTypesOfWork = (types) => {
    setForm((current) => applyTypesOfWorkChange(current, types));
  };

  const confirmPresetWorkType = (payload) => {
    setForm((current) => applyPresetWorkTypeConfirm(current, payload));
  };

  const updateBlockTasks = (blockId, tasks) => {
    setForm((current) => ({
      ...current,
      blocks: window.WorkPlanEditor.syncProjectDependencies(
        current.blocks.map((block) => block.id === blockId ? { ...block, tasks } : block)
      )
    }));
  };

  const validateStep = () => {
    if (step === 1 && (!form.name.trim() || !form.startDate || !form.endDate)) {
      window.ConstructProData.showToast("Add project name, start date, and end date.");
      return false;
    }
    if (step === 2) {
      if (!form.blocks.some((block) => block.name.trim())) {
        window.ConstructProData.showToast("Add at least one block or structure.");
        return false;
      }
      const taskCount = form.blocks.reduce((n, b) => n + (b.tasks?.length || 0), 0);
      if (taskCount === 0) {
        window.ConstructProData.showToast("Add at least one task — select work types or add tasks manually.");
        return false;
      }
      if (window.WorkPlanEditor.calculateProjectBudget(form) === 0) {
        window.ConstructProData.showToast("Total estimated budget is zero. Review labor and material estimates.");
      }
    }
    return true;
  };

  const submit = () => {
    const payload = normalizeProjectForm(form);
    if (mode === "edit") {
      window.ConstructProData.updateProject(activeProject.id, payload);
      window.ConstructProData.showToast("Active project updated.");
    } else {
      window.ConstructProData.createProject(payload);
      window.ConstructProData.showToast("Project created and initialized.");
    }
    setMode("edit");
    setStep(1);
  };

  const next = () => {
    if (!validateStep()) return;
    if (step < CREATE_PROJECT_STEPS.length) {
      setStep((current) => current + 1);
      return;
    }
    submit();
  };

  const previous = () => setStep((current) => Math.max(1, current - 1));

  return (
    <div className="fade-in">
      <div className="mb-6 flex flex-wrap items-center gap-2">
        <Button variant={mode === "create" ? "primary" : "secondary"} onClick={resetCreate}><Icons.plus /> New Project</Button>
        <Button variant={mode === "edit" ? "primary" : "secondary"} onClick={editActive}>Edit Active</Button>
      </div>

      <div className="mb-6 grid grid-cols-1 gap-4 xl:grid-cols-3">
        {activeProjects.map((project) => (
          <Card key={project.id} className={`project-progress-card ${project.id === activeProject.id ? "border-primary/50 bg-primary-fixed/40" : ""}`}>
            <div className="flex items-start justify-between gap-3">
              <div>
                <h3 className="font-bold text-text-primary">{project.name}</h3>
                <p className="mt-1 text-sm text-text-muted">{project.code} · {project.location}</p>
              </div>
              <Badge tone={project.id === activeProject.id ? "success" : "neutral"}>{project.id === activeProject.id ? "active" : project.status}</Badge>
            </div>
            <div className="mt-4 rounded-xl border border-border-light bg-white p-3">
              <div className="mb-3 flex items-center justify-between text-sm">
                <span className="font-semibold text-text-muted">Progress</span>
                <span className="font-bold text-primary">{project.progressPct || 0}%</span>
              </div>
              <ProgressBar value={project.progressPct} />
              <ProjectPhaseTrack project={project} />
            </div>
            <div className="mt-4 flex flex-wrap gap-2">
              <Button variant="secondary" disabled={project.id === activeProject.id} onClick={() => window.ConstructProData.setActiveProject(project.id)}>Set Active</Button>
              <Button variant="ghost" onClick={() => { window.ConstructProData.setActiveProject(project.id); setMode("edit"); }}>Edit</Button>
              <Button variant="danger" disabled={activeProjects.length <= 1} onClick={() => window.ConstructProData.archiveProject(project.id)}>Archive</Button>
            </div>
          </Card>
        ))}
      </div>

      <Card pad="p-0" className="overflow-hidden">
        <WizardSteps currentStep={step} />
        <div className="p-5 md:p-8">
          {step === 1 && <ProjectBasicsStep form={form} update={update} />}
          {step === 2 && <WorkTypesStep form={form} update={update} setTypesOfWork={setTypesOfWork} confirmPresetWorkType={confirmPresetWorkType} addBlock={addBlock} removeBlock={removeBlock} updateBlock={updateBlock} updateBlockTasks={updateBlockTasks} importTasks={importTasks} />}
          {step === 3 && <TeamMoneyStep form={form} update={update} updateNested={updateNested} users={users} />}
          {step === 4 && <ReviewStep form={form} users={users} onEditStep={setStep} />}
        </div>
        <div className="flex items-center justify-between border-t border-border-light bg-surface-container-low px-5 py-4">
          <Button type="button" variant="secondary" disabled={step === 1} onClick={previous}>Back</Button>
          <Button type="button" onClick={next}>{step === CREATE_PROJECT_STEPS.length ? (mode === "edit" ? "Save Project" : "Create Project") : "Next Step"}</Button>
        </div>
      </Card>
    </div>
  );
}

function ProjectModal({ open, mode = "create", initialStep = 1, snapshot, onClose }) {
  const activeProject = snapshot.project;
  const users = snapshot.users || [];
  const [modalMode, setModalMode] = React.useState(mode);
  const [step, setStep] = React.useState(initialStep);
  const [form, setForm] = React.useState(() => mode === "edit" ? projectToForm(activeProject, users) : newProjectForm(activeProject, users));

  React.useEffect(() => {
    if (!open) return;
    setModalMode(mode);
    setStep(initialStep || 1);
    setForm(mode === "edit" ? projectToForm(activeProject, users) : newProjectForm(activeProject, users));
  }, [open, mode, initialStep, activeProject.id]);

  if (!open) return null;

  const update = (key, value) => setForm((current) => ({ ...current, [key]: value }));
  const updateNested = (group, key, value) => setForm((current) => ({ ...current, [group]: { ...current[group], [key]: value } }));
  const updateBlock = (id, key, value) => setForm((current) => ({
    ...current,
    blocks: current.blocks.map((block) => block.id === id ? { ...block, [key]: value } : block)
  }));
  const addBlock = () => setForm((current) => {
    const block = createBlock(current.blocks.length + 1);
    const schedule = { projectStart: current.startDate || "", projectEnd: current.endDate || "" };
    return {
      ...current,
      blocks: window.WorkPlanEditor.syncPresetTasksForAllBlocks(
        [...current.blocks, block],
        current.typesOfWork,
        current.presetDefaults,
        schedule
      )
    };
  });
  const removeBlock = (id) => setForm((current) => {
    const nextBlocks = current.blocks.filter((block) => block.id !== id);
    return { ...current, blocks: nextBlocks.length ? nextBlocks : [createBlock(1)] };
  });
  const importTasks = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    const rows = await parseTaskFile(file);
    if (!rows.length) {
      window.ConstructProData.showToast("No task rows found. Use task_name, block_name, target_days, estimated_budget.");
      return;
    }
    setForm((current) => ({
      ...current,
      blocks: window.WorkPlanEditor.mergeImportedTasksIntoBlocks(current.blocks, rows)
    }));
    window.ConstructProData.showToast(`${rows.length} task rows imported into blocks.`);
  };
  const setTypesOfWork = (types) => {
    setForm((current) => applyTypesOfWorkChange(current, types));
  };

  const confirmPresetWorkType = (payload) => {
    setForm((current) => applyPresetWorkTypeConfirm(current, payload));
  };
  const updateBlockTasks = (blockId, tasks) => {
    setForm((current) => ({
      ...current,
      blocks: window.WorkPlanEditor.syncProjectDependencies(
        current.blocks.map((block) => block.id === blockId ? { ...block, tasks } : block)
      )
    }));
  };
  const validateStep = () => {
    if (step === 1 && (!form.name.trim() || !form.startDate || !form.endDate)) {
      window.ConstructProData.showToast("Add project name, start date, and end date.");
      return false;
    }
    if (step === 2) {
      if (!form.blocks.some((block) => block.name.trim())) {
        window.ConstructProData.showToast("Add at least one block or structure.");
        return false;
      }
      const taskCount = form.blocks.reduce((n, b) => n + (b.tasks?.length || 0), 0);
      if (taskCount === 0) {
        window.ConstructProData.showToast("Add at least one task — select work types or add tasks manually.");
        return false;
      }
      if (window.WorkPlanEditor.calculateProjectBudget(form) === 0) {
        window.ConstructProData.showToast("Total estimated budget is zero. Review labor and material estimates.");
      }
    }
    return true;
  };
  const submit = () => {
    const payload = normalizeProjectForm(form);
    if (modalMode === "edit") {
      window.ConstructProData.updateProject(activeProject.id, payload);
    } else {
      window.ConstructProData.createProject(payload);
    }
    onClose();
  };
  const next = () => {
    if (!validateStep()) return;
    if (step < CREATE_PROJECT_STEPS.length) {
      setStep((current) => current + 1);
      return;
    }
    submit();
  };
  const previous = () => setStep((current) => Math.max(1, current - 1));

  return (
    <div className="project-modal-overlay" role="presentation" onClick={onClose}>
      <div className="project-modal-shell">
        <section
          role="dialog"
          aria-modal="true"
          aria-labelledby="project-modal-title"
          className="project-modal-surface"
          onClick={(event) => event.stopPropagation()}
        >
          <div className="project-modal-header m3-sheet-header">
            <div className="min-w-0 flex-1 pr-2">
              <p className="text-xs font-medium tracking-wide text-on-surface-variant">Project setup wizard</p>
              <h2 id="project-modal-title" className="m3-sheet-header__title">{modalMode === "edit" ? "Edit Active Project" : "Create New Project"}</h2>
              <p className="m3-sheet-header__subtitle">{modalMode === "edit" ? activeProject.name : "Add basics, buildings, team, and budget without leaving the portfolio."}</p>
            </div>
            <div className="flex items-center gap-2">
              {modalMode === "edit" && <Button variant="secondary" onClick={() => { setModalMode("create"); setStep(1); setForm(newProjectForm(activeProject, users)); }}>Switch to New</Button>}
              <button type="button" onClick={onClose} aria-label="Close project modal" className="m3-icon-button m3-icon-button--tonal">
                <Icons.close size={24} />
              </button>
            </div>
          </div>
          <WizardSteps currentStep={step} />
          <div className="project-modal-body">
            {step === 1 && <ProjectBasicsStep form={form} update={update} />}
            {step === 2 && <WorkTypesStep form={form} update={update} setTypesOfWork={setTypesOfWork} confirmPresetWorkType={confirmPresetWorkType} addBlock={addBlock} removeBlock={removeBlock} updateBlock={updateBlock} updateBlockTasks={updateBlockTasks} importTasks={importTasks} />}
            {step === 3 && <TeamMoneyStep form={form} update={update} updateNested={updateNested} users={users} />}
            {step === 4 && <ReviewStep form={form} users={users} onEditStep={setStep} />}
          </div>
          <div className="project-modal-footer">
            <Button type="button" variant="secondary" disabled={step === 1} onClick={previous}>Back</Button>
            <div className="flex items-center gap-2">
              <span className="hidden text-xs font-semibold text-text-muted sm:inline">Step {step} of {CREATE_PROJECT_STEPS.length}</span>
              <Button type="button" onClick={next}>{step === CREATE_PROJECT_STEPS.length ? (modalMode === "edit" ? "Save Project" : "Create Project") : "Next Step"}</Button>
            </div>
          </div>
        </section>
      </div>
    </div>
  );
}

function WizardSteps({ currentStep }) {
  const isPhone = useIsPhone();
  const current = CREATE_PROJECT_STEPS.find((item) => item.id === currentStep);

  if (isPhone) {
    return (
      <div className="border-b border-border-light bg-surface-container-low px-4 py-3">
        <p className="text-xs font-semibold uppercase tracking-wide text-text-muted">Step {currentStep} of {CREATE_PROJECT_STEPS.length}</p>
        <p className="mt-1 text-sm font-bold text-primary">{current?.title}</p>
        <div className="mt-3 flex gap-1" aria-hidden="true">
          {CREATE_PROJECT_STEPS.map((item) => (
            <span
              key={item.id}
              className={`h-1 flex-1 rounded-full ${item.id <= currentStep ? "bg-primary" : "bg-border-light"}`}
            />
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="overflow-x-auto border-b border-border-light bg-surface-container-low px-4 py-4 md:px-5">
      <div className="flex min-w-0 items-center justify-between gap-2 md:gap-3">
        {CREATE_PROJECT_STEPS.map((item, index) => {
          const complete = item.id < currentStep;
          const active = item.id === currentStep;
          return (
            <React.Fragment key={item.id}>
              <div className={`flex min-w-0 items-center gap-2 text-sm font-bold ${active ? "text-primary" : complete ? "text-success" : "text-text-muted"}`}>
                <span className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs ${active ? "bg-primary text-white" : complete ? "bg-success/10 text-success" : "bg-gray-200 text-text-muted"}`}>
                  {complete ? <Icons.check size={14} /> : item.id}
                </span>
                <span className="hidden truncate lg:inline">{item.title}</span>
              </div>
              {index < CREATE_PROJECT_STEPS.length - 1 && <div className="hidden h-px min-w-[1rem] flex-1 bg-border-light sm:block" />}
            </React.Fragment>
          );
        })}
      </div>
    </div>
  );
}

function ProjectBasicsStep({ form, update }) {
  return (
    <div className="space-y-6">
      <StepIntro title="1. Project Basics & Site Location" text="Enter name, duration, site address, and map boundary details." />
      <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
        <Field label="Project Name" value={form.name} onChange={(value) => update("name", value)} required placeholder="Residential Tower Project" />
        <SelectField label="Project Type" value={form.type} onChange={(value) => update("type", value)}>
          <option>Residential Building</option>
          <option>Commercial Complex</option>
          <option>Infrastructure / Roads</option>
          <option>G+4 twin-block residential apartments</option>
        </SelectField>
        <Field
          label="Project Start Date"
          type="date"
          value={form.startDate}
          onChange={(value) => {
            update("startDate", value);
            updateFoundationConfig(form, update, { startDate: value });
          }}
          required
          placeholder="Select start date"
        />
        <Field
          label="Project End Date"
          type="date"
          value={form.endDate}
          onChange={(value) => update("endDate", value)}
          required
          placeholder="Select end date"
        />
        <label className="md:col-span-2" htmlFor="project-address">
          <span className="mb-1 block text-xs font-bold uppercase tracking-wider text-text-muted">Site Address</span>
          <textarea id="project-address" value={form.address} onChange={(event) => update("address", event.target.value)} placeholder="Enter full site address details..." className="min-h-20 w-full rounded-lg border border-border-light px-3 py-2 transition-colors focus:border-cta" />
        </label>
        <Field label="City / Location" value={form.location} onChange={(value) => update("location", value)} placeholder="e.g. Bhubaneswar, Odisha" />
        <Field label="Project Code" value={form.code} onChange={(value) => update("code", value)} placeholder="Auto if blank" />
      </div>
      <SiteMapPicker
        latitude={form.gpsLatitude}
        longitude={form.gpsLongitude}
        radiusMeters={form.geofenceRadiusMeters}
        address={form.address}
        locationHint={form.location}
        onCoordinatesChange={({ latitude, longitude }) => {
          if (latitude !== undefined) update("gpsLatitude", latitude == null || latitude === "" ? "" : String(latitude));
          if (longitude !== undefined) update("gpsLongitude", longitude == null || longitude === "" ? "" : String(longitude));
        }}
        onRadiusChange={(value) => update("geofenceRadiusMeters", value)}
        onAddressChange={(value) => {
          if (value) update("address", value);
        }}
      />
    </div>
  );
}

function WorkTypesStep({ form, update, setTypesOfWork, confirmPresetWorkType, addBlock, removeBlock, updateBlock, updateBlockTasks, importTasks }) {
  const [customType, setCustomType] = React.useState("");
  const [taskFilter, setTaskFilter] = React.useState("all");
  const [collapsedBlocks, setCollapsedBlocks] = React.useState(() => new Set());
  const [presetModal, setPresetModal] = React.useState(null);
  const fileInputRef = React.useRef(null);
  const defaultTargetDays = form.blocks?.[0]?.targetDays || 30;

  const openPresetModal = (draft) => setPresetModal(draft);
  const closePresetModal = () => setPresetModal(null);

  const handlePresetConfirm = (payload) => {
    confirmPresetWorkType(payload);
    closePresetModal();
  };

  const addCustom = (e) => {
    if (e) e.preventDefault();
    const name = customType.trim();
    if (!name || form.typesOfWork.includes(name)) return;
    const dates = window.WorkPlanEditor.defaultTaskDates({
      projectStart: form.startDate || "",
      projectEnd: form.endDate || "",
      targetDays: defaultTargetDays
    });
    openPresetModal({
      mode: "add",
      workType: name,
      targetDays: defaultTargetDays,
      budgetPlanned: 0,
      hasBreakdown: true,
      labor: window.WorkPlanEditor.emptyTaskBreakdown(defaultTargetDays).labor,
      materials: [],
      startDate: dates.startDate,
      dueDate: dates.dueDate
    });
    setCustomType("");
  };

  const toggleCompleted = (type) => {
    const isCompleted = form.completedWorkTypes.includes(type);
    if (isCompleted) {
      update("completedWorkTypes", form.completedWorkTypes.filter(t => t !== type));
    } else {
      update("completedWorkTypes", [...form.completedWorkTypes, type]);
    }
  };

  const toggleBlockCollapse = (blockId) => {
    setCollapsedBlocks((current) => {
      const next = new Set(current);
      if (next.has(blockId)) next.delete(blockId);
      else next.add(blockId);
      return next;
    });
  };

  const PRESETS = DEFAULT_TYPES_OF_WORK;
  const blockListRef = React.useRef(null);
  const prevBlockCountRef = React.useRef(form.blocks.length);

  React.useEffect(() => {
    if (form.blocks.length > prevBlockCountRef.current) {
      const lastId = form.blocks[form.blocks.length - 1]?.id;
      if (lastId) {
        requestAnimationFrame(() => {
          document.getElementById(`block-panel-${lastId}`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
        });
      }
    }
    prevBlockCountRef.current = form.blocks.length;
  }, [form.blocks.length]);

  const handleAddBlock = () => {
    addBlock();
  };

  const focusProjectTask = (blockId, taskId) => {
    setCollapsedBlocks((current) => {
      const next = new Set(current);
      next.delete(blockId);
      return next;
    });
    requestAnimationFrame(() => {
      document.getElementById(`block-panel-${blockId}`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
      const row = document.querySelector(`[data-task-id="${taskId}"]`);
      if (row) {
        row.classList.add("work-item-draft-row--highlight");
        window.setTimeout(() => row.classList.remove("work-item-draft-row--highlight"), 1800);
      }
    });
  };

  return (
    <div className="space-y-6">
      <StepIntro title="2. Work Types & Project Structure" text="Select work types to seed tasks, then configure each block and its task tree with estimated budgets." compact />

      <WorkTypeChipPicker
        presets={PRESETS}
        selected={form.typesOfWork}
        defaultTargetDays={defaultTargetDays}
        projectStartDate={form.startDate}
        projectEndDate={form.endDate}
        onChange={setTypesOfWork}
        onOpenPresetModal={openPresetModal}
        onClearAll={() => {
          setTypesOfWork([]);
          update("completedWorkTypes", []);
        }}
        customType={customType}
        setCustomType={setCustomType}
        onAddCustom={addCustom}
      />

      {/* Phase Overview Panel - Shows after selection */}
      <PhaseOverviewPanel
        phases={form.typesOfWork}
        presetDefaults={form.presetDefaults}
        completedPhases={form.completedWorkTypes}
        projectStatus={form.projectStatus}
      />

      {form.typesOfWork.includes("Foundation Work") ? (
        <FoundationPlanPanel
          config={form.foundationConfig || defaultFoundationFormConfig(form.startDate)}
          location={form.location}
          projectStartDate={form.startDate}
          onChange={(next) => update("foundationConfig", next)}
          onApply={() => {
            const next = applyFoundationPlanToForm(form);
            update("foundationConfig", next.foundationConfig);
            update("presetDefaults", next.presetDefaults);
            update("blocks", next.blocks);
            window.ConstructProData.showToast("Foundation BOQ applied — 16 sequential subtasks added.");
          }}
        />
      ) : null}

      <PresetWorkTypeModal
        open={Boolean(presetModal)}
        draft={presetModal}
        blockCount={form.blocks?.length || 1}
        projectStartDate={form.startDate}
        projectEndDate={form.endDate}
        onClose={closePresetModal}
        onConfirm={handlePresetConfirm}
      />

      <div className="space-y-4" ref={blockListRef}>
        <div className="flex flex-wrap items-center justify-between gap-2">
          <div>
            <h3 className="text-xs font-bold uppercase tracking-wider text-text-muted">Work plan</h3>
            <p className="mt-0.5 text-sm text-text-muted">Each block holds its own task tree — name, floor, and tasks in one place.</p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <WorkPlanFilterBar filter={taskFilter} onChange={setTaskFilter} />
            <Button type="button" variant="secondary" onClick={handleAddBlock}><Icons.plus /> Add block</Button>
          </div>
        </div>
        <div className="space-y-3">
          {form.blocks.map((block, index) => (
            <BlockWorkPlanPanel
              key={block.id}
              block={block}
              blockIndex={index}
              projectBlocks={form.blocks}
              projectStartDate={form.startDate}
              projectEndDate={form.endDate}
              filter={taskFilter}
              collapsed={collapsedBlocks.has(block.id)}
              onToggleCollapse={() => toggleBlockCollapse(block.id)}
              onUpdateTasks={(tasks) => updateBlockTasks(block.id, tasks)}
              onUpdateBlock={(key, value) => updateBlock(block.id, key, value)}
              onRemoveBlock={() => removeBlock(block.id)}
              canRemoveBlock={form.blocks.length > 1}
            />
          ))}
        </div>
        {form.blocks.length === 0 && (
          <p className="rounded-xl border border-dashed border-border-light bg-surface-container-low p-8 text-center text-sm text-text-muted">
            No blocks yet. Click &ldquo;Add block&rdquo; to define a building or structure.
          </p>
        )}
        <ProjectDependencyOverview blocks={form.blocks} onFocusTask={focusProjectTask} />
        <WizardBudgetSummary form={form} />
      </div>

      <div className="rounded-xl border border-border-light bg-white p-5">
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <h3 className="text-xs font-bold uppercase tracking-wider text-text-muted">Import Tasks (Optional)</h3>
          <input type="file" accept=".csv,.xlsx" ref={fileInputRef} onChange={importTasks} className="hidden" />
          <Button type="button" variant="secondary" onClick={() => fileInputRef.current?.click()}><Icons.plus /> Import CSV / XLSX</Button>
        </div>
        <p className="text-xs text-text-muted">
          Format: <code className="rounded bg-slate-100 px-1">task_name, block_name, target_days, estimated_budget</code>
        </p>
        <p className="mt-1 text-xs text-text-muted">
          <a className="font-semibold text-primary hover:underline" href="../samples/work-program-template.csv" download="work-program-template.csv">CSV template</a>
          {" · "}
          <a className="font-semibold text-primary hover:underline" href="../samples/work-program-template.xlsx" download="work-program-template.xlsx">Excel template</a>
        </p>
      </div>

      {/* New vs Ongoing Segment */}
      <div className="rounded-xl border border-border-light bg-surface-container-low p-5">
        <h3 className="mb-3 text-xs font-bold uppercase tracking-wider text-text-muted">Project Onboarding Status</h3>
        <div className="flex gap-2">
          <button
            type="button"
            className={`flex-1 py-3 px-4 rounded-xl border text-sm font-bold transition-all ${form.projectStatus === "new" ? "border-primary bg-primary text-white shadow-md" : "border-border-light bg-white text-text-primary hover:bg-gray-50"}`}
            onClick={() => {
              update("projectStatus", "new");
              update("completedWorkTypes", []);
            }}
          >
            New Project
          </button>
          <button
            type="button"
            className={`flex-1 py-3 px-4 rounded-xl border text-sm font-bold transition-all ${form.projectStatus === "ongoing" ? "border-primary bg-primary text-white shadow-md" : "border-border-light bg-white text-text-primary hover:bg-gray-50"}`}
            onClick={() => update("projectStatus", "ongoing")}
          >
            Ongoing Project
          </button>
        </div>
        <p className="mt-2 text-xs text-text-muted">
          {form.projectStatus === "new"
            ? "All tasks and subtasks will start as 'To Do' by default."
            : "Mark phases that have already been executed. The system will auto-approve and lock their actual progress & budget."}
        </p>
      </div>

      {/* Ongoing Completed Work Types Selection */}
      {form.projectStatus === "ongoing" && form.typesOfWork.length > 0 && (
        <div className="rounded-xl border border-border-light bg-surface-container-low p-5 fade-in">
          <h3 className="mb-3 text-xs font-bold uppercase tracking-wider text-text-muted">Mark Completed Work Types</h3>
          <p className="text-sm text-text-muted mb-4">Select the phases that are already finished on-site (e.g. Foundation Work):</p>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
            {form.typesOfWork.map((type) => {
              const completed = form.completedWorkTypes.includes(type);
              return (
                <button
                  key={type}
                  type="button"
                  onClick={() => toggleCompleted(type)}
                  className={`flex items-center justify-between p-4 rounded-xl border text-left font-bold transition-all ${completed ? "border-success bg-success/5 text-success shadow-sm" : "border-border-light bg-white text-text-primary hover:bg-gray-50"}`}
                >
                  <span>{type}</span>
                  <span className={`h-5 w-5 rounded-full flex items-center justify-center border ${completed ? "bg-success border-success text-white" : "border-border-light bg-white"}`}>
                    {completed && <Icons.check size={12} />}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

function TeamMoneyStep({ form, update, updateNested, users }) {
  const syncTeamSize = (teamAssignments) => {
    update("teamSize", countAssignedTeam(teamAssignments));
  };

  const setTeamRole = (key, user) => {
    const next = {
      ...form.teamAssignments,
      [key]: user?.name || "",
      [`${key}Id`]: user?.id || ""
    };
    update("teamAssignments", next);
    syncTeamSize(next);
  };

  const toggleSiteEngineer = (user) => {
    const current = form.teamAssignments?.siteEngineers || [];
    const currentIds = form.teamAssignments?.siteEngineerIds || [];
    const selected = current.includes(user.name);
    const siteEngineers = selected ? current.filter((name) => name !== user.name) : [...current, user.name];
    const siteEngineerIds = selected ? currentIds.filter((id) => id !== user.id) : [...currentIds, user.id];
    const next = { ...form.teamAssignments, siteEngineers, siteEngineerIds };
    update("teamAssignments", next);
    syncTeamSize(next);
  };

  return (
    <div className="space-y-6">
      <StepIntro title="3. Assign Team" text="Pick a small site team for this project — manager, QC, and field crew." />
      <ProjectTeamAssign
        users={users}
        teamAssignments={form.teamAssignments}
        onSetProjectManager={(user) => setTeamRole("projectManager", user)}
        onSetQcEngineer={(user) => setTeamRole("qcEngineer", user)}
        onToggleSiteEngineer={toggleSiteEngineer}
      />
      <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
        <Field label="Client" value={form.client} onChange={(value) => update("client", value)} placeholder="Client name" />
        <div className="rounded-xl border border-border-light bg-surface-container-low/50 px-4 py-3">
          <p className="text-xs font-bold uppercase tracking-wider text-text-muted">Team size</p>
          <p className="mt-1 text-2xl font-bold text-text-primary">{countAssignedTeam(form.teamAssignments)}</p>
          <p className="mt-1 text-xs text-text-muted">Auto-counted from assigned members</p>
        </div>
      </div>
    </div>
  );
}

function ProjectTeamAssign({ users, teamAssignments, onSetProjectManager, onSetQcEngineer, onToggleSiteEngineer, compact = false }) {
  const managers = users.filter((user) => user.role === "Project Manager" || user.role === "Admin");
  const qcOptions = users.filter((user) => user.role === "Field Team Member" || user.role === "Project Manager");
  const siteCrew = users.filter((user) => user.role === "Field Team Member" || user.role === "Contractor");
  const selectedSite = new Set(teamAssignments?.siteEngineers || []);

  if (!users.length) {
    return (
      <div className="project-team-empty rounded-xl border border-dashed border-border-light bg-gray-50 px-4 py-6 text-center">
        <Icons.users size={28} className="mx-auto mb-2 text-text-muted" />
        <p className="text-sm font-semibold text-text-primary">No team members yet</p>
        <p className="mt-1 text-xs text-text-muted">Add users in Settings to assign a project team.</p>
      </div>
    );
  }

  return (
    <div className={`project-team-assign${compact ? " project-team-assign--compact" : ""}`}>
      <div className="project-team-assign__roles">
        <TeamRolePicker
          label="Project Manager"
          hint="Owns delivery and approvals"
          users={managers}
          value={teamAssignments?.projectManager || ""}
          onSelect={onSetProjectManager}
        />
        <TeamRolePicker
          label="QC Engineer"
          hint="Checks quality on site"
          users={qcOptions}
          value={teamAssignments?.qcEngineer || ""}
          onSelect={onSetQcEngineer}
        />
      </div>
      <div className="project-team-assign__crew">
        <div className="project-team-assign__crew-head">
          <p className="project-team-assign__crew-title">Site crew</p>
          <p className="project-team-assign__crew-hint">Tap to add or remove field members</p>
        </div>
        <div className="project-team-chip-list">
          {siteCrew.map((user) => {
            const active = selectedSite.has(user.name);
            return (
              <button
                key={user.id}
                type="button"
                className={`project-team-chip${active ? " is-active" : ""}`}
                aria-pressed={active}
                onClick={() => onToggleSiteEngineer?.(user)}
              >
                <span className="project-team-chip__avatar" aria-hidden="true">{teamMemberInitials(user.name)}</span>
                <span className="project-team-chip__body">
                  <span className="project-team-chip__name">{user.name}</span>
                  <span className="project-team-chip__role">{user.role}</span>
                </span>
                {active ? <Icons.check size={16} className="project-team-chip__check" /> : null}
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function TeamRolePicker({ label, hint, users, value, onSelect }) {
  const selected = users.find((user) => user.name === value) || null;
  return (
    <label className="project-team-role">
      <span className="project-team-role__label">{label}</span>
      <span className="project-team-role__hint">{hint}</span>
      <div className="project-team-role__select-wrap">
        {selected ? (
          <span className="project-team-role__avatar" aria-hidden="true">{teamMemberInitials(selected.name)}</span>
        ) : (
          <span className="project-team-role__avatar project-team-role__avatar--empty" aria-hidden="true">+</span>
        )}
        <select
          className="project-team-role__select"
          value={value || ""}
          onChange={(event) => {
            const user = users.find((entry) => entry.name === event.target.value) || null;
            onSelect(user);
          }}
        >
          <option value="">Select {label.toLowerCase()}</option>
          {users.map((user) => (
            <option key={user.id} value={user.name}>{user.name} · {user.role}</option>
          ))}
        </select>
      </div>
    </label>
  );
}

function ProjectTeamSummary({ teamAssignments, users = [], onEdit }) {
  const members = listTeamMembers(teamAssignments, users);
  if (!members.length) {
    return (
      <div className="project-team-summary project-team-summary--empty">
        <div>
          <p className="project-team-summary__title">Project team</p>
          <p className="project-team-summary__empty">No team assigned yet</p>
        </div>
        {onEdit ? (
          <Button variant="secondary" className="!text-xs" onClick={onEdit}>Assign team</Button>
        ) : null}
      </div>
    );
  }

  return (
    <div className="project-team-summary">
      <div className="project-team-summary__head">
        <div>
          <p className="project-team-summary__title">Project team</p>
          <p className="project-team-summary__meta">{members.length} member{members.length === 1 ? "" : "s"} assigned</p>
        </div>
        {onEdit ? (
          <Button variant="ghost" className="!text-xs" onClick={onEdit}>Edit team</Button>
        ) : null}
      </div>
      <div className="project-team-summary__list">
        {members.map((member) => (
          <div key={`${member.roleLabel}-${member.name}`} className="project-team-summary__member">
            <span className="project-team-summary__avatar" aria-hidden="true">{teamMemberInitials(member.name)}</span>
            <div className="min-w-0">
              <p className="truncate font-semibold text-text-primary">{member.name}</p>
              <p className="text-xs text-text-muted">{member.roleLabel}</p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function teamMemberInitials(name = "") {
  return String(name)
    .trim()
    .split(/\s+/)
    .slice(0, 2)
    .map((part) => part.charAt(0).toUpperCase())
    .join("") || "?";
}

function countAssignedTeam(teamAssignments = {}) {
  const names = new Set();
  if (teamAssignments.projectManager) names.add(teamAssignments.projectManager);
  if (teamAssignments.qcEngineer) names.add(teamAssignments.qcEngineer);
  (teamAssignments.siteEngineers || []).forEach((name) => { if (name) names.add(name); });
  return names.size;
}

function listTeamMembers(teamAssignments = {}, users = []) {
  const byName = new Map(users.map((user) => [user.name, user]));
  const members = [];
  if (teamAssignments.projectManager) {
    members.push({
      name: teamAssignments.projectManager,
      roleLabel: "Project Manager",
      user: byName.get(teamAssignments.projectManager)
    });
  }
  if (teamAssignments.qcEngineer && teamAssignments.qcEngineer !== teamAssignments.projectManager) {
    members.push({
      name: teamAssignments.qcEngineer,
      roleLabel: "QC Engineer",
      user: byName.get(teamAssignments.qcEngineer)
    });
  }
  (teamAssignments.siteEngineers || []).forEach((name) => {
    if (!name || members.some((member) => member.name === name)) return;
    members.push({
      name,
      roleLabel: byName.get(name)?.role || "Site crew",
      user: byName.get(name)
    });
  });
  return members;
}

function ReviewStep({ form, users = [], onEditStep }) {
  const ff = window.ConstructProData.formatCurrency;
  const blocks = (form.blocks || []).filter((block) => block.name?.trim());
  const taskCount = blocks.reduce((count, block) => count + (block.tasks?.length || 0), 0);
  const total = window.WorkPlanEditor.calculateProjectBudget(form);
  const teamMembers = listTeamMembers(form.teamAssignments, users);
  const durationLabel = reviewDurationLabel(form.startDate, form.endDate);
  const hasGps = Boolean(form.gpsLatitude && form.gpsLongitude);

  return (
    <div className="project-review">
      <header className="project-review__intro">
        <div className="min-w-0">
          <p className="project-review__eyebrow">Step 4 · Final check</p>
          <h2 className="project-review__title">Review &amp; confirm</h2>
          <p className="project-review__subtitle">Check the summary below. Tap any section to edit before you create the project.</p>
        </div>
        <div className="project-review__ready" aria-hidden="true">
          <Icons.check size={18} />
          <span>Ready</span>
        </div>
      </header>

      <section className="project-review-hero" aria-label="Project summary">
        <div className="project-review-hero__main">
          <p className="project-review-hero__label">Project</p>
          <h3 className="project-review-hero__name">{form.name?.trim() || "Untitled project"}</h3>
          <p className="project-review-hero__meta">
            {[form.type, form.location || form.address].filter(Boolean).join(" · ") || "Details pending"}
          </p>
          <div className="project-review-hero__badges">
            <span className={`project-review-pill${form.projectStatus === "ongoing" ? " project-review-pill--ongoing" : ""}`}>
              {form.projectStatus === "ongoing" ? "Ongoing project" : "New project"}
            </span>
            {form.client ? <span className="project-review-pill project-review-pill--client">{form.client}</span> : null}
          </div>
        </div>
        <div className="project-review-hero__stats">
          <ReviewStat label="Total budget" value={ff(total)} highlight />
          <ReviewStat label="Timeline" value={durationLabel} />
          <ReviewStat label="Blocks" value={String(blocks.length)} />
          <ReviewStat label="Team" value={String(teamMembers.length || countAssignedTeam(form.teamAssignments))} />
        </div>
      </section>

      <div className="project-review-grid">
        <ReviewCard title="Project basics" icon={<Icons.project size={18} />} step={1} onEdit={onEditStep}>
          <ReviewFactList items={[
            { label: "Dates", value: form.startDate && form.endDate ? `${form.startDate} → ${form.endDate}` : "—" },
            { label: "Location", value: form.location || form.address || "—" },
            {
              label: "Site GPS",
              value: hasGps
                ? `${form.gpsLatitude}, ${form.gpsLongitude} · ${form.geofenceRadiusMeters || 150} m geofence`
                : "Not pinned"
            }
          ]} />
        </ReviewCard>

        <ReviewCard title="Team" icon={<Icons.users size={18} />} step={3} onEdit={onEditStep}>
          {teamMembers.length ? (
            <div className="project-review-team">
              {teamMembers.map((member) => (
                <div key={`${member.roleLabel}-${member.name}`} className="project-review-team__member">
                  <span className="project-review-team__avatar">{teamMemberInitials(member.name)}</span>
                  <div className="min-w-0">
                    <p className="project-review-team__name">{member.name}</p>
                    <p className="project-review-team__role">{member.roleLabel}</p>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <p className="project-review-empty">No team assigned yet</p>
          )}
        </ReviewCard>

        <ReviewCard title="Work plan" icon={<Icons.schedule size={18} />} step={2} onEdit={onEditStep} wide>
          <div className="project-review-plan">
            {blocks.map((block) => {
              const tasks = window.WorkPlanEditor.flattenBlockTasks(block);
              const blockBudget = tasks.reduce((sum, task) => sum + (task.type === "qc" ? 0 : Number(task.budgetPlanned || 0)), 0);
              return (
                <article key={block.id} className="project-review-block">
                  <div className="project-review-block__head">
                    <div className="min-w-0">
                      <p className="project-review-block__name">{block.name}</p>
                      {block.floor ? <p className="project-review-block__floor">{block.floor}</p> : null}
                    </div>
                    <div className="project-review-block__meta">
                      <span>{tasks.length} task{tasks.length === 1 ? "" : "s"}</span>
                      <span className="project-review-block__budget">{ff(blockBudget)}</span>
                    </div>
                  </div>
                  <ul className="project-review-task-list">
                    {tasks.map((task) => (
                      <li
                        key={task.id}
                        className="project-review-task"
                        style={{ "--review-task-indent": `${Math.min(task.level || 0, 3) * 0.75}rem` }}
                      >
                        <div className="project-review-task__main">
                          <span className={`project-review-task__type project-review-task__type--${task.type || "task"}`}>
                            {task.type === "subtask" ? "Sub" : task.type === "qc" ? "QC" : "Task"}
                          </span>
                          <span className="project-review-task__title">{task.title}</span>
                          {task.isPreset ? <span className="project-review-task__preset">Preset</span> : null}
                        </div>
                        {task.type !== "qc" ? (
                          <div className="project-review-task__stats">
                            <span>{ff(task.budgetPlanned || 0)}</span>
                            <span>{task.targetDays || 0}d</span>
                          </div>
                        ) : (
                          <span className="project-review-task__stats project-review-task__stats--muted">Quality gate</span>
                        )}
                      </li>
                    ))}
                  </ul>
                </article>
              );
            })}
          </div>
          <p className="project-review-plan__footer">
            {blocks.length} block{blocks.length === 1 ? "" : "s"} · {taskCount} work item{taskCount === 1 ? "" : "s"} · {ff(total)} estimated
          </p>
        </ReviewCard>

        <ReviewCard title="Onboarding" icon={<Icons.check size={18} />} step={2} onEdit={onEditStep}>
          <ReviewFactList items={[
            {
              label: "Project mode",
              value: form.projectStatus === "ongoing" ? "Ongoing — partial work already complete" : "New — starting from scratch"
            },
            {
              label: "Completed phases",
              value: form.projectStatus === "ongoing" && form.completedWorkTypes?.length
                ? form.completedWorkTypes.join(", ")
                : "None marked"
            }
          ]} />
        </ReviewCard>
      </div>
    </div>
  );
}

function ReviewStat({ label, value, highlight = false }) {
  return (
    <div className={`project-review-stat${highlight ? " project-review-stat--highlight" : ""}`}>
      <span className="project-review-stat__label">{label}</span>
      <span className="project-review-stat__value">{value}</span>
    </div>
  );
}

function ReviewCard({ title, icon, step, onEdit, wide = false, children }) {
  return (
    <section className={`project-review-card${wide ? " project-review-card--wide" : ""}`}>
      <div className="project-review-card__head">
        <div className="project-review-card__title-wrap">
          <span className="project-review-card__icon" aria-hidden="true">{icon}</span>
          <h3 className="project-review-card__title">{title}</h3>
        </div>
        <button type="button" className="project-review-card__edit" onClick={() => onEdit(step)}>
          Edit
        </button>
      </div>
      <div className="project-review-card__body">{children}</div>
    </section>
  );
}

function ReviewFactList({ items = [] }) {
  return (
    <dl className="project-review-facts">
      {items.map((item) => (
        <div key={item.label} className="project-review-facts__row">
          <dt>{item.label}</dt>
          <dd>{item.value}</dd>
        </div>
      ))}
    </dl>
  );
}

function reviewDurationLabel(startDate, endDate) {
  if (!startDate || !endDate) return "—";
  const start = new Date(`${startDate}T12:00:00`).getTime();
  const end = new Date(`${endDate}T12:00:00`).getTime();
  if (Number.isNaN(start) || Number.isNaN(end) || end < start) return `${startDate} → ${endDate}`;
  const days = Math.max(1, Math.ceil((end - start) / 86400000));
  const months = Math.max(1, Math.round(days / 30));
  return `${months} mo · ${days} days`;
}

function PhaseOverviewPanel({ phases, presetDefaults, completedPhases, projectStatus }) {
  if (!phases || phases.length === 0) {
    return null;
  }

  const totalDays = phases.reduce((sum, phase) => {
    const defaults = presetDefaults?.[phase];
    return sum + (defaults?.targetDays || 30);
  }, 0);

  const totalBudget = phases.reduce((sum, phase) => {
    const defaults = presetDefaults?.[phase];
    return sum + (defaults?.budgetPlanned || 0);
  }, 0);

  const ff = window.ConstructProData.formatCurrency;

  return (
    <Card className="phase-overview-panel">
      <div className="flex items-start justify-between gap-4 mb-4">
        <div>
          <h3 className="text-xs font-bold uppercase tracking-wider text-text-muted">Construction Phases</h3>
          <p className="mt-1 text-sm text-text-muted">
            {phases.length} phase{phases.length !== 1 ? "s" : ""} · {totalDays} days · {ff(totalBudget)}
          </p>
        </div>
        <Badge tone="primary">{phases.length} phases</Badge>
      </div>

      {/* Phase Timeline */}
      <div className="phase-timeline-wrap mb-4">
        <div className="relative h-2 bg-surface-container-low rounded-full overflow-hidden">
          {phases.map((phase, index) => {
            const defaults = presetDefaults?.[phase] || {};
            const phaseDays = defaults.targetDays || 30;
            const widthPct = totalDays > 0 ? (phaseDays / totalDays) * 100 : 100 / phases.length;
            const isCompleted = completedPhases?.includes(phase);
            return (
              <div
                key={phase}
                className={`absolute top-0 h-full transition-all ${isCompleted ? "bg-success" : "bg-primary"}`}
                style={{
                  left: `${phases.slice(0, index).reduce((sum, p) => {
                    const d = presetDefaults?.[p]?.targetDays || 30;
                    return sum + (totalDays > 0 ? (d / totalDays) * 100 : 100 / phases.length);
                  }, 0)}%`,
                  width: `${widthPct}%`,
                  opacity: isCompleted ? 0.5 : 1
                }}
              />
            );
          })}
        </div>
      </div>

      {/* Phase Cards */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
        {phases.map((phase, index) => {
          const defaults = presetDefaults?.[phase] || {};
          const phaseDays = defaults.targetDays || 30;
          const phaseBudget = defaults.budgetPlanned || 0;
          const isCompleted = completedPhases?.includes(phase);
          return (
            <div
              key={phase}
              className={`rounded-xl border p-4 transition-all ${isCompleted ? "border-success bg-success/5" : "border-border-light bg-white"}`}
            >
              <div className="flex items-start justify-between gap-2 mb-2">
                <div className="flex items-center gap-2">
                  <span className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold ${isCompleted ? "bg-success text-white" : "bg-primary/10 text-primary"}`}>
                    {isCompleted ? "✓" : index + 1}
                  </span>
                  <span className="text-xs font-bold text-text-primary">{compactPhaseLabel(phase)}</span>
                </div>
              </div>
              <div className="flex items-center justify-between text-xs text-text-muted mt-3">
                <span>{phaseDays} days</span>
                <span className="font-semibold">{ff(phaseBudget)}</span>
              </div>
            </div>
          );
        })}
      </div>

      {projectStatus === "ongoing" && completedPhases && completedPhases.length > 0 && (
        <div className="mt-4 pt-4 border-t border-border-light">
          <p className="text-xs text-text-muted">
            <Icons.check className="inline mr-1" size={14} />
            <span className="font-semibold text-success">{completedPhases.length} phase{completedPhases.length !== 1 ? "s" : ""} marked as completed</span>
          </p>
        </div>
      )}
    </Card>
  );
}

function ProjectPhaseTrack({ project }) {
  const phases = getProjectPhases(project);
  if (!phases.length) return null;
  const activeIndex = getProjectPhaseIndex(project, phases.length);
  const progress = Number(project.progressPct || 0);

  return (
    <div className="project-phase-track mt-4">
      <div className="project-phase-rail-wrap relative mb-3 h-8">
        <div className="project-phase-rail absolute left-0 right-0 top-1/2 h-1 -translate-y-1/2 rounded-full" />
        <div className="project-phase-rail-fill absolute left-0 top-1/2 h-1 -translate-y-1/2 rounded-full" style={{ width: `${progress}%` }} />
        <div className="relative flex items-center justify-between">
          {phases.map((phase, index) => {
            const completed = index < activeIndex;
            const current = index === activeIndex;
            return (
              <div
                key={`${project.id}-${phase}`}
                className="project-phase-item relative z-10"
                style={{ animationDelay: `${index * 40}ms` }}
              >
                <div className={`project-phase-dot flex h-8 w-8 items-center justify-center rounded-full border text-xs font-bold ${completed ? "border-success bg-success text-white" : current ? "project-phase-dot--active border-primary bg-primary text-white" : "border-outline-variant bg-white text-text-muted"}`}>
                  {completed ? "✓" : index + 1}
                </div>
              </div>
            );
          })}
        </div>
      </div>
      <div className="grid grid-cols-5 gap-2">
        {phases.map((phase, index) => (
          <span key={`${project.id}-${phase}-label`} className={`project-phase-label truncate text-center text-xs font-semibold ${index <= activeIndex ? "text-text-primary" : "text-text-muted"}`} title={phase}>
            {phase}
          </span>
        ))}
      </div>
    </div>
  );
}

function StepIntro({ title, text, compact = false }) {
  return (
    <div className={compact ? "" : "border-b border-border-light pb-4"}>
      <h2 className="text-lg font-bold text-text-primary">{title}</h2>
      <p className="mt-1 text-sm text-text-muted">{text}</p>
    </div>
  );
}

function createBlock(index) {
  return {
    id: `block_${Date.now()}_${Math.random().toString(36).slice(2, 6)}_${index}`,
    name: index === 1 ? "Block A" : `Block ${String.fromCharCode(64 + index)}`,
    floor: "",
    targetDays: 120,
    tasks: []
  };
}

function emptyProjectForm(reference = {}, users = []) {
  const manager = users.find((user) => user.role === "Project Manager" || user.role === "Admin")?.name || "";
  const siteEngineers = users.filter((user) => user.role === "Field Team Member" || user.role === "Contractor").slice(0, 2).map((user) => user.name);
  const qcEngineer = users.find((user) => user.role === "Field Team Member" || user.role === "Project Manager")?.name || "";
  return {
    name: "",
    code: "",
    type: reference.type || "Residential Building",
    client: "",
    location: "",
    address: "",
    startDate: "",
    endDate: "",
    gpsLatitude: reference.gps?.latitude != null ? String(reference.gps.latitude) : "",
    gpsLongitude: reference.gps?.longitude != null ? String(reference.gps.longitude) : "",
    geofenceRadiusMeters: reference.geofenceRadiusMeters || 150,
    blocks: [createBlock(1)],
    starterTasks: [],
    projectStatus: "new",
    typesOfWork: [],
    presetDefaults: {},
    floor: "",
    completedWorkTypes: [],
    alertRules: { enabled: true, frequency: 2, windowSec: 30 },
    qualityRules: { concreteLevel: true, thickness: true, crackInspection: true, curing: true },
    reminderRules: { vendorPayout: true, laborPayout: true, materialOrdering: true },
    teamAssignments: {
      projectManager: manager,
      projectManagerId: users.find((user) => user.name === manager)?.id || "",
      siteEngineers,
      siteEngineerIds: users.filter((user) => siteEngineers.includes(user.name)).map((user) => user.id),
      qcEngineer,
      qcEngineerId: users.find((user) => user.name === qcEngineer)?.id || ""
    },
    budgetTotal: "",
    budgetUsed: 0,
    teamSize: 12,
    units: "",
    foundationConfig: defaultFoundationFormConfig()
  };
}

function newProjectForm(reference = {}, users = []) {
  return {
    ...emptyProjectForm(reference, users),
    type: "Residential Building",
    typesOfWork: [],
    presetDefaults: {},
    projectStatus: "new",
    completedWorkTypes: []
  };
}

function projectToForm(project, users = []) {
  const base = emptyProjectForm(project, users);
  return {
    ...base,
    name: project.name || "",
    code: project.code || "",
    type: project.type || "Residential Building",
    client: project.client || "",
    location: project.location || "",
    address: project.address || "",
    startDate: project.startDate || "",
    endDate: project.endDate || "",
    gpsLatitude: project.gps?.latitude || "",
    gpsLongitude: project.gps?.longitude || "",
    geofenceRadiusMeters: project.geofenceRadiusMeters || 150,
    blocks: normalizeBlocksForForm(project.blocks, project.floor, project.typesOfWork),
    starterTasks: Array.isArray(project.starterTasks) ? project.starterTasks : [],
    projectStatus: project.projectStatus || "new",
    typesOfWork: Array.isArray(project.typesOfWork) ? [...project.typesOfWork] : [],
    presetDefaults: window.WorkPlanEditor.inferPresetDefaultsFromBlocks(
      normalizeBlocksForForm(project.blocks, project.floor, project.typesOfWork),
      Array.isArray(project.typesOfWork) ? project.typesOfWork : []
    ),
    floor: project.floor || "",
    completedWorkTypes: project.completedWorkTypes || [],
    alertRules: { ...base.alertRules, ...(project.alertRules || {}) },
    qualityRules: { ...base.qualityRules, ...(project.qualityRules || {}) },
    reminderRules: { ...base.reminderRules, ...(project.reminderRules || {}) },
    teamAssignments: { ...base.teamAssignments, ...(project.teamAssignments || {}) },
    budgetTotal: project.budgetTotal || 0,
    budgetUsed: project.budgetUsed || 0,
    teamSize: project.teamSize || 0,
    units: project.units || 0,
    foundationConfig: {
      ...defaultFoundationFormConfig(project.startDate),
      ...(project.foundationConfig || {})
    }
  };
}

function normalizeBlocksForForm(blocks, projectFloor = "", typesOfWork = []) {
  if (!Array.isArray(blocks) || !blocks.length) {
    return window.WorkPlanEditor.syncPresetTasksForAllBlocks([createBlock(1)], typesOfWork);
  }
  return blocks.map((block, index) => {
    const fallback = createBlock(index + 1);
    let normalized;
    if (typeof block === "string") {
      normalized = { ...fallback, name: block, floor: index === 0 ? (projectFloor || "") : "" };
    } else {
      normalized = {
        ...fallback,
        ...block,
        id: block.id || fallback.id,
        floor: String((block.floor ?? (index === 0 ? projectFloor : "")) || "").trim(),
        targetDays: Number(block.targetDays || 120),
        tasks: Array.isArray(block.tasks) ? block.tasks : []
      };
    }
    if (!normalized.tasks?.length && typesOfWork?.length) {
      return window.WorkPlanEditor.syncPresetTasksForBlock(normalized, typesOfWork);
    }
    return normalized;
  });
}

function normalizeProjectForm(form) {
  return {
    name: form.name.trim(),
    code: form.code.trim(),
    type: form.type,
    client: form.client,
    location: form.location,
    address: form.address,
    startDate: form.startDate,
    endDate: form.endDate,
    geofenceRadiusMeters: Number(form.geofenceRadiusMeters) || 150,
    gps: {
      latitude: Number(form.gpsLatitude) || null,
      longitude: Number(form.gpsLongitude) || null
    },
    blocks: form.blocks
      .filter((block) => block.name.trim())
      .map((block) => ({
        id: block.id,
        name: block.name.trim(),
        floor: String(block.floor || "").trim(),
        targetDays: Number(block.targetDays) || 0,
        tasks: (block.tasks || []).map((task) => {
          const isQc = task.type === "qc";
          const stripped = isQc ? window.WorkPlanEditor.stripQcScheduling(task) : task;
          return {
            id: stripped.id,
            title: String(stripped.title || "").trim(),
            type: stripped.type || "task",
            parentTaskId: stripped.parentTaskId || null,
            workTypeName: stripped.workTypeName || null,
            isPreset: Boolean(stripped.isPreset),
            targetDays: isQc ? 0 : (Number(stripped.targetDays) || 0),
            startDate: isQc ? "" : (stripped.startDate || form.startDate || ""),
            dueDate: isQc ? "" : (stripped.dueDate || form.endDate || ""),
            budgetPlanned: isQc ? 0 : (Number(stripped.budgetPlanned) || window.WorkPlanEditor.calculateEstimateBudget(stripped)),
            labor: isQc ? window.WorkPlanEditor.emptyQcBreakdown().labor : (stripped.labor || {}),
            materials: isQc ? [] : (stripped.materials || []),
            progressPct: 0,
            dependencyEnabled: Boolean(stripped.dependencyEnabled),
            dependencyTaskId: stripped.dependencyTaskId || null,
            dependencyPosition: stripped.dependencyPosition === "before" ? "before" : "after",
            dependsOnTaskId: stripped.dependsOnTaskId || null
          };
        })
      })),
    starterTasks: form.starterTasks,
    projectStatus: form.projectStatus,
    typesOfWork: form.typesOfWork,
    floor: String(form.blocks.find((block) => block.name.trim())?.floor || form.floor || "").trim(),
    completedWorkTypes: form.completedWorkTypes,
    alertRules: {
      enabled: Boolean(form.alertRules.enabled),
      frequency: Number(form.alertRules.frequency) || 0,
      windowSec: Number(form.alertRules.windowSec) || 30
    },
    qualityRules: form.qualityRules,
    reminderRules: form.reminderRules,
    teamAssignments: form.teamAssignments,
    budgetTotal: window.WorkPlanEditor.calculateProjectBudget(form),
    budgetUsed: Number(form.budgetUsed) || 0,
    teamSize: countAssignedTeam(form.teamAssignments) || Number(form.teamSize) || 0,
    units: Number(form.units) || 0,
    foundationConfig: form.foundationConfig || null
  };
}

function getProjectPhases(project) {
  const source = Array.isArray(project.typesOfWork) ? project.typesOfWork.filter(Boolean) : [];
  return source.map(compactPhaseLabel);
}

function compactPhaseLabel(label) {
  return String(label)
    .replace(/\s*work\s*/ig, " ")
    .replace(/\s*&\s*/g, " ")
    .replace(/\s+/g, " ")
    .trim();
}

function getProjectPhaseIndex(project, phaseCount) {
  const completed = Array.isArray(project.completedWorkTypes) ? project.completedWorkTypes.length : 0;
  if (completed > 0) return Math.min(phaseCount - 1, completed);
  const pct = Number(project.progressPct || 0);
  return Math.min(phaseCount - 1, Math.max(0, Math.round((pct / 100) * (phaseCount - 1))));
}

function parseCsvTasks(text) {
  return rowsToStarterTasks(
    text
      .split(/\r?\n/)
      .map((line) => line.trim())
      .filter(Boolean)
      .map((line, index) => {
        const cells = line.split(",").map((cell) => cell.trim()).filter(Boolean);
        if (!cells.length) return null;
        return { task_name: cells[0], block_name: cells[1], target_days: cells[2], estimated_budget: cells[3], _index: index };
      })
      .filter(Boolean)
  );
}

async function parseTaskFile(file) {
  const name = String(file?.name || "").toLowerCase();
  if (name.endsWith(".xlsx")) {
    if (!window.XLSX) {
      window.ConstructProData.showToast("Excel support failed to load. Please use CSV.");
      return [];
    }
    try {
      const buffer = await file.arrayBuffer();
      const workbook = window.XLSX.read(buffer, { type: "array" });
      const sheetName = workbook.SheetNames?.[0];
      if (!sheetName) return [];
      const worksheet = workbook.Sheets[sheetName];
      const rows = window.XLSX.utils.sheet_to_json(worksheet, { defval: "" });
      return rowsToStarterTasks(rows);
    } catch (_) {
      window.ConstructProData.showToast("Could not read XLSX. Please verify the file format.");
      return [];
    }
  }
  const text = await file.text();
  return parseCsvTasks(text);
}

function rowsToStarterTasks(rows) {
  if (!Array.isArray(rows)) return [];
  return rows
    .map((row, index) => {
      const taskName = row.task_name || row.task || row.title || row.name || "";
      const blockName = row.block_name || row.block || row.structure || "";
      const targetDaysRaw = row.target_days ?? row.days ?? row.duration ?? "";
      const title = String(taskName).trim();
      if (!title) return null;
      if (index === 0 && /task|name|title/i.test(title) && String(blockName).trim()) return null;
      const budgetRaw = row.estimated_budget ?? row.budget ?? row.estimated_budget ?? "";
      return {
        id: `imported_${Date.now()}_${index}`,
        title,
        blockName: String(blockName || "").trim(),
        targetDays: Number(targetDaysRaw) || 30,
        type: String(row.type || row.task_type || "task").toLowerCase(),
        budgetPlanned: Number(budgetRaw) || 0
      };
    })
    .filter(Boolean)
    .slice(0, 40);
}

function SelectField({ label, value, onChange, children }) {
  const id = `field-${label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}`;
  return (
    <label htmlFor={id}>
      <span className="mb-1 block text-xs font-bold uppercase tracking-wider text-text-muted">{label}</span>
      <select id={id} value={value} onChange={(event) => onChange(event.target.value)} className="w-full rounded-lg border border-border-light px-3 py-2 transition-colors focus:border-cta">
        {children}
      </select>
    </label>
  );
}

function Field({ label, value, onChange, type = "text", required = false, placeholder = "", step }) {
  const id = `field-${label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}`;
  const numeric = type === "number";
  return (
    <label htmlFor={id}>
      <span className="mb-1 block text-xs font-bold uppercase tracking-wider text-text-muted">{label}</span>
      <input id={id} type={type} step={step} inputMode={numeric ? "decimal" : undefined} required={required} value={value} placeholder={placeholder} onChange={(event) => onChange(event.target.value)} className="w-full rounded-lg border border-border-light px-3 py-2 transition-colors focus:border-cta" />
    </label>
  );
}

function defaultFoundationFormConfig(projectStartDate = "") {
  const Foundation = window.ConstructProFoundationPlan;
  if (!Foundation) {
    return {
      foundationType: "isolated_footing",
      columnCount: 8,
      useDetailedPlan: true,
      startDate: projectStartDate || "",
      applied: false
    };
  }
  return {
    ...Foundation.defaultFoundationConfig({ startDate: projectStartDate }),
    applied: false
  };
}

function updateFoundationConfig(form, update, patch) {
  update("foundationConfig", {
    ...(form.foundationConfig || defaultFoundationFormConfig(form.startDate)),
    ...patch
  });
}

function applyFoundationPlanToForm(form) {
  const Foundation = window.ConstructProFoundationPlan;
  if (!Foundation) return form;
  const options = {
    ...(form.foundationConfig || defaultFoundationFormConfig(form.startDate)),
    location: form.location,
    startDate: form.startDate || form.foundationConfig?.startDate || ""
  };
  const plan = Foundation.buildFoundationPlan(options);
  const presetPatch = window.WorkPlanEditor.foundationPresetDefaultsFromPlan(plan);
  return {
    ...form,
    foundationConfig: { ...options, applied: true },
    presetDefaults: { ...form.presetDefaults, ...presetPatch },
    blocks: window.WorkPlanEditor.applyFoundationPlanToAllBlocks(form.blocks, options)
  };
}

function applyTypesOfWorkChange(current, types) {
  const blockTargetDays = current.blocks?.[0]?.targetDays || 30;
  const presetDefaults = window.WorkPlanEditor.normalizePresetDefaults(types, current.presetDefaults, blockTargetDays);
  const schedule = { projectStart: current.startDate || "", projectEnd: current.endDate || "" };
  let next = {
    ...current,
    typesOfWork: types,
    presetDefaults,
    blocks: window.WorkPlanEditor.syncPresetTasksForAllBlocks(current.blocks, types, presetDefaults, schedule)
  };
  const hasFoundation = types.includes("Foundation Work");
  const wantsDetail = next.foundationConfig?.useDetailedPlan !== false;
  const foundationAdded = hasFoundation && !current.typesOfWork.includes("Foundation Work");
  if (hasFoundation && wantsDetail && (foundationAdded || !next.foundationConfig?.applied)) {
    next = applyFoundationPlanToForm(next);
  }
  return next;
}

function applyPresetWorkTypeConfirm(current, {
  workType,
  targetDays,
  budgetPlanned,
  labor,
  materials,
  hasBreakdown,
  startDate,
  dueDate,
  isNew
}) {
  let types = current.typesOfWork || [];
  if (isNew && !types.includes(workType)) {
    types = [...types, workType];
  }
  const blockTargetDays = current.blocks?.[0]?.targetDays || 30;
  const schedule = { projectStart: current.startDate || "", projectEnd: current.endDate || "" };
  const fallbackDates = window.WorkPlanEditor.defaultTaskDates({
    projectStart: schedule.projectStart,
    projectEnd: schedule.projectEnd,
    targetDays: Number(targetDays) || blockTargetDays
  });
  const presetDefaults = {
    ...(current.presetDefaults || {}),
    [workType]: {
      targetDays: Number(targetDays) || blockTargetDays,
      budgetPlanned: Number(budgetPlanned) || 0,
      hasBreakdown: hasBreakdown !== false,
      labor: labor || window.WorkPlanEditor.emptyTaskBreakdown(Number(targetDays) || blockTargetDays).labor,
      materials: Array.isArray(materials) ? materials : [],
      startDate: startDate || fallbackDates.startDate,
      dueDate: dueDate || fallbackDates.dueDate
    }
  };
  const normalized = window.WorkPlanEditor.normalizePresetDefaults(types, presetDefaults, blockTargetDays);
  return {
    ...current,
    typesOfWork: types,
    presetDefaults: normalized,
    blocks: window.WorkPlanEditor.syncPresetTasksForAllBlocks(current.blocks, types, normalized, schedule)
  };
}

Object.assign(window, {
  CreateProject,
  ProjectModal,
  ProjectTeamAssign,
  ProjectTeamSummary,
  countAssignedTeam,
  listTeamMembers,
  teamMemberInitials
});
