"use client";

import { useState, useEffect } from "react";
import { Card, Button, Dialog, DialogContent } from "ikoncomponents";
import StepIndicator from "./components/StepIndicator";
import MeetingStep from "./components/steps/MeetingStep";
import AttendeesStep from "./components/steps/AttendeesStep";
import AgendaStep from "./components/steps/AgendaStep";
import DecisionsStep from "./components/steps/DecisionsStep";
import ActionsStep from "./components/steps/ActionsStep";
import OthersStep from "./components/steps/OthersStep";

import { STEPS, cn, getInitialFormData } from "./lib/utils";
import { stepKeys } from "./lib/constants";
import { validateStep, stepHasErrors, StepErrors } from "./lib/validation";
import { FormData, StepKey, ApiUser } from "./types";

interface MeetingResponse {
  id: string;
  meeting: {
    title: string;
    projectName: string;
    place: string;
    date: string;
    time: string;
    duration: string;
    calledBy: string;
  };
  attendees: { attendees: { name: string; role: string; contact: string }[] };
  agenda: { agenda: { item: string; owner: string }[] };
  decisions: { decisions: string[] };
  actions: { actions: { item: string; responsible: string; dueDate: string }[] };
  others: { notes: string };
  projectIdentifier: string;
  status: "Draft" | "Completed";
  createdAt: string;
  updatedAt: string;
}

interface MeetingDetailsFormProps {
  open: boolean;
  setOpen: (open: boolean) => void;
  onSubmit: (data: FormData & { projectIdentifier: string }) => Promise<void>;
  projectIdentifier: string;
  projectName: string;
  initialData?: MeetingResponse | null;
}

export default function MeetingDetailsForm({
  open,
  setOpen,
  onSubmit,
  projectIdentifier,
  projectName,
  initialData,
}: MeetingDetailsFormProps) {
  const [currentStep, setCurrentStep] = useState<number>(1);
  const [saveStatus, setSaveStatus] = useState<"idle" | "draft" | "success" | "error">("idle");
  const [users, setUsers] = useState<ApiUser[]>([]);
  const [stepErrors, setStepErrors] = useState<Record<number, StepErrors>>({});

  // ─── Build form data from initialData (edit) or blank (new) ───────────────
  const buildFormData = (): FormData => {
    if (initialData) {
      return {
        meeting: {
          title: initialData.meeting.title ?? "",
          projectName: initialData.meeting.projectName ?? projectName,
          place: initialData.meeting.place ?? "",
          date: initialData.meeting.date ?? "",
          time: initialData.meeting.time ?? "",
          duration: initialData.meeting.duration ?? "",
          durationUnit: "minutes",
          calledBy: initialData.meeting.calledBy ?? "",
          externalCalledBy: "",
        },
        attendees: initialData.attendees ?? { attendees: [] },
        agenda: initialData.agenda ?? { agenda: [] },
        decisions: initialData.decisions ?? { decisions: [] },
        actions: initialData.actions ?? { actions: [] },
        others: initialData.others ?? { notes: "" },
      };
    }
    return getInitialFormData(projectName);
  };

  const [formData, setFormData] = useState<FormData>(buildFormData);

  // Re-populate whenever initialData changes (switching between drafts or new)
  useEffect(() => {
    setFormData(buildFormData());
    setCurrentStep(1);
    setStepErrors({});
    setSaveStatus("idle");
  }, [initialData, open]);

  // ─── Helpers ──────────────────────────────────────────────────────────────
  const getStepData = (step: number) => {
    const key = stepKeys[step - 1] as StepKey;
    return formData[key];
  };

  const runValidation = (step: number): StepErrors => {
    const errors = validateStep(step, getStepData(step));
    setStepErrors((prev) => ({ ...prev, [step]: errors }));
    return errors;
  };

  const errorsForStep = (step: number): StepErrors => stepErrors[step] ?? {};

  const errorSteps = Object.entries(stepErrors)
    .filter(([, errs]) => Object.keys(errs).length > 0)
    .map(([s]) => Number(s));

  // ─── Data update ──────────────────────────────────────────────────────────
  const updateStepData = (step: number, field: string, value: unknown) => {
    const key = stepKeys[step - 1] as StepKey;
    setFormData((prev) => {
      const updated = { ...prev, [key]: { ...prev[key], [field]: value } };
      if (stepErrors[step]) {
        const errors = validateStep(step, updated[key]);
        setStepErrors((e) => ({ ...e, [step]: errors }));
      }
      return updated;
    });
  };

  // ─── Build payload ────────────────────────────────────────────────────────
  const buildPayload = (
    allValid: boolean
  ): FormData & { projectIdentifier: string; status: "Completed" | "Draft" } => {
    const { meeting, attendees, agenda, decisions, actions, others } = formData;

    const meetingPayload = Object.fromEntries(
      Object.entries(meeting).filter(
        ([key]) => key !== "durationUnit" && key !== "externalCalledBy"
      )
    ) as typeof meeting;

    return {
      meeting: meetingPayload,
      attendees: {
        attendees: attendees.attendees.filter(
          (a) => a.name?.trim() || a.role?.trim() || a.contact?.trim()
        ),
      },
      agenda: {
        agenda: agenda.agenda.filter((a) => a.item?.trim() || a.owner?.trim()),
      },
      decisions: {
        decisions: decisions.decisions.filter((d) => d?.trim()),
      },
      actions: {
        actions: actions.actions.filter(
          (a) => a.item?.trim() || a.responsible?.trim() || a.dueDate?.trim()
        ),
      },
      others: { notes: others.notes?.trim() ?? "" },
      projectIdentifier,
      status: allValid ? "Completed" : "Draft",
    };
  };

  // ─── Navigation ───────────────────────────────────────────────────────────
  const handleNext = () => {
    const errors = runValidation(currentStep);
    if (Object.keys(errors).length > 0) return;
    setCurrentStep((s) => s + 1);
  };

  const handlePrev = () => setCurrentStep((s) => s - 1);

  // ─── Save ─────────────────────────────────────────────────────────────────
  const handleSave = async () => {
    const allValid = Array.from({ length: 6 }, (_, i) => i + 1).every(
      (step) => Object.keys(validateStep(step, getStepData(step))).length === 0
    );
    try {
      await onSubmit(buildPayload(allValid));
      setSaveStatus(allValid ? "success" : "draft");
    } catch (err) {
      console.error("Failed to save meeting:", err);
      setSaveStatus("error");
    }
  };

  // ─── Close ────────────────────────────────────────────────────────────────
  const handleClose = () => {
    setOpen(false);
    setSaveStatus("idle");
    setCurrentStep(1);
    setStepErrors({});
  };

  // ─── Step renderer ────────────────────────────────────────────────────────
  const renderStep = () => {
    switch (currentStep) {
      case 1:
        return (
          <MeetingStep
            data={formData.meeting}
            onChange={(f, v) => updateStepData(1, f, v)}
            errors={errorsForStep(1)}
          />
        );
      case 2:
        return (
          <AttendeesStep
            data={formData.attendees}
            onChange={(f, v) => updateStepData(2, f, v)}
            onUsersLoaded={setUsers}
            errors={errorsForStep(2)}
          />
        );
      case 3:
        return (
          <AgendaStep
            data={formData.agenda}
            onChange={(f, v) => updateStepData(3, f, v)}
            attendees={formData.attendees.attendees}
            users={users}
            errors={errorsForStep(3)}
          />
        );
      case 4:
        return (
          <DecisionsStep
            data={formData.decisions}
            onChange={(f, v) => updateStepData(4, f, v)}
            errors={errorsForStep(4)}
          />
        );
      case 5:
        return (
          <ActionsStep
            data={formData.actions}
            onChange={(f, v) => updateStepData(5, f, v)}
            errors={errorsForStep(5)}
          />
        );
      case 6:
        return (
          <OthersStep
            data={formData.others}
            onChange={(f, v) => updateStepData(6, f, v)}
            errors={errorsForStep(6)}
          />
        );
      default:
        return null;
    }
  };

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="max-w-5xl! w-full p-0 h-4/5 max-h-xl">
        <Card className="overflow-hidden border-0 shadow-none">
          {/* Header */}
          <div className="px-6 pt-5 pb-4 border-b border-slate-100">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-lg font-bold">
                {initialData ? "Continue Editing" : "Meeting Details"}
              </h2>
            </div>
            <StepIndicator currentStep={currentStep} errors={errorSteps} />
          </div>

          {/* Body */}
          <div className="px-6 py-5 max-h-2xl! h-full overflow-auto">
            {saveStatus === "success" && (
              <div className="mb-4 p-3 rounded-lg bg-emerald-50 border border-emerald-200 text-emerald-700 text-sm font-medium">
                ✓ Meeting details saved successfully!
              </div>
            )}
            {saveStatus === "error" && (
              <div className="mb-4 p-3 rounded-lg bg-red-50 border border-red-200 text-red-700 text-sm font-medium">
                ✗ Failed to save meeting. Check the console for details and try again.
              </div>
            )}
            {renderStep()}
          </div>

          {/* Footer */}
          <div className="px-6 py-4 border-t border-slate-100 flex items-center justify-between">
            <div>
              {currentStep > 1 && (
                <Button variant="outline" onClick={handlePrev}>
                  ← Prev
                </Button>
              )}
            </div>
            <div className="flex items-center gap-3">
              {currentStep < 6 && (
                <Button variant="outline" onClick={handleNext}>
                  Next →
                </Button>
              )}
              <Button onClick={handleSave}>Save</Button>
            </div>
          </div>
        </Card>
      </DialogContent>
    </Dialog>
  );
}