"use client";
import { useState } from "react";
import { Plus, Pencil, Trash2 } from "lucide-react";
import { Panel, StatusBadge, PreviewNotice } from "@/components/shared/page";
import { Field, SelectField } from "@/components/shared/field";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { currency } from "@/lib/format";
import { emptyParticipant, emptyTerm } from "./fixtures";
import {
  contractTypes,
  contractTypeLabels,
  validateTerm,
  type Participant,
  type ContractTerm,
} from "./model";
export function Participants({
  participants,
  onChange,
  readonly = false,
}: {
  participants: Participant[];
  onChange: (participants: Participant[]) => void;
  readonly?: boolean;
}) {
  const [editing, setEditing] = useState<Participant | null>(null),
    [term, setTerm] = useState<{
      participantId: string;
      value: ContractTerm;
    } | null>(null),
    [error, setError] = useState(""),
    [deleting, setDeleting] = useState<{
      participantId: string;
      termId?: string;
    } | null>(null);
  const saveParticipant = (event: React.FormEvent) => {
    event.preventDefault();
    if (!editing?.name.trim()) {
      setError("Participant name is required.");
      return;
    }
    const next = { ...editing, id: editing.id || crypto.randomUUID() };
    onChange(
      participants.some((row) => row.id === next.id)
        ? participants.map((row) => (row.id === next.id ? next : row))
        : [...participants, next],
    );
    setEditing(null);
  };
  const saveTerm = (event: React.FormEvent) => {
    event.preventDefault();
    if (!term) return;
    const invalid = validateTerm(term.value);
    if (invalid) {
      setError(invalid);
      return;
    }
    const owner = participants.find((row) => row.id === term.participantId);
    const shared = participants.some(
      (row) =>
        row.id !== owner?.id &&
        row.terms.length &&
        ((row.role === "Site Manager" && owner?.role === "Site Manager") ||
          (row.role === "Investor" &&
            owner?.role === "Investor" &&
            row.group &&
            row.group === owner.group)),
    );
    if (shared) {
      setError(
        "This site manager role or investor group already has terms on another participant.",
      );
      return;
    }
    const value = { ...term.value, id: term.value.id || crypto.randomUUID() };
    onChange(
      participants.map((row) =>
        row.id === term.participantId
          ? {
              ...row,
              terms: row.terms.some((item) => item.id === value.id)
                ? row.terms.map((item) => (item.id === value.id ? value : item))
                : [...row.terms, value],
            }
          : row,
      ),
    );
    setTerm(null);
  };
  return (
    <>
      <Panel
        title="Contract Participants"
        description="Participants, investor groups, representatives, and individual contract terms."
      >
        <div className="flex justify-end p-5">
          {!readonly && (
            <Button
              type="button"
              onClick={() => {
                setError("");
                setEditing({ ...emptyParticipant });
              }}
            >
              <Plus className="size-4" />
              Add Participant
            </Button>
          )}
        </div>
        {!participants.length && (
          <p className="px-5 pb-8 text-center text-sm text-muted-foreground">
            No participants yet. Add a participant to configure revenue shares
            or fixed payments.
          </p>
        )}
        <div className="divide-y">
          {participants.map((participant) => (
            <div className="p-5" key={participant.id}>
              <div className="flex flex-wrap justify-between gap-3">
                <div>
                  <h3 className="font-medium">
                    {participant.name}{" "}
                    <span className="ml-2 text-xs text-muted-foreground">
                      {participant.role}
                    </span>
                  </h3>
                  <p className="mt-1 text-xs text-muted-foreground">
                    {participant.group || "No investor group"} · Priority{" "}
                    {participant.priority}
                    {participant.representative
                      ? " · Representative"
                      : ""} ·{" "}
                    <StatusBadge>
                      {participant.active ? "Active" : "Inactive"}
                    </StatusBadge>
                  </p>
                </div>
                {!readonly && (
                  <div className="flex items-center gap-2">
                    <Button
                      type="button"
                      size="sm"
                      variant="outline"
                      onClick={() => {
                        setError("");
                        setTerm({
                          participantId: participant.id,
                          value: { ...emptyTerm },
                        });
                      }}
                    >
                      Add Term
                    </Button>
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      aria-label={`Edit ${participant.name}`}
                      onClick={() => {
                        setError("");
                        setEditing({ ...participant });
                      }}
                    >
                      <Pencil className="size-4" />
                    </Button>
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      aria-label={`Delete ${participant.name}`}
                      onClick={() =>
                        setDeleting({ participantId: participant.id })
                      }
                    >
                      <Trash2 className="size-4 text-destructive" />
                    </Button>
                  </div>
                )}
              </div>
              {participant.terms.length > 0 && (
                <div className="mt-4 overflow-x-auto rounded-lg border">
                  <table className="data-table">
                    <thead>
                      <tr>
                        <th>Contract Type</th>
                        <th>Share / Fixed</th>
                        <th>Frequency</th>
                        <th>Validity</th>
                        <th>Minimum / Cap</th>
                        {!readonly && <th>Actions</th>}
                      </tr>
                    </thead>
                    <tbody>
                      {participant.terms.map((item) => (
                        <tr key={item.id}>
                          <td>{contractTypeLabels[item.type]}</td>
                          <td>
                            {item.type === "FIXED_COST"
                              ? currency(item.fixed)
                              : `${item.share}%`}
                          </td>
                          <td>
                            {item.frequency} · Day {item.dueDay}
                          </td>
                          <td>
                            {item.validFrom} → {item.validTo || "Ongoing"}
                          </td>
                          <td>
                            {currency(item.minimum)} /{" "}
                            {item.cap ? currency(item.cap) : "No cap"}
                          </td>
                          {!readonly && (
                            <td>
                              <div className="flex gap-2">
                                <Button
                                  type="button"
                                  size="icon"
                                  variant="ghost"
                                  aria-label={`Edit term for ${participant.name}`}
                                  onClick={() => {
                                    setError("");
                                    setTerm({
                                      participantId: participant.id,
                                      value: { ...item },
                                    });
                                  }}
                                >
                                  <Pencil className="size-4" />
                                </Button>
                                <Button
                                  type="button"
                                  size="icon"
                                  variant="ghost"
                                  aria-label={`Delete term for ${participant.name}`}
                                  onClick={() =>
                                    setDeleting({
                                      participantId: participant.id,
                                      termId: item.id,
                                    })
                                  }
                                >
                                  <Trash2 className="size-4 text-destructive" />
                                </Button>
                              </div>
                            </td>
                          )}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          ))}
        </div>
      </Panel>
      <Dialog
        open={!!editing}
        onOpenChange={(open) => {
          if (!open) setEditing(null);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {editing?.id ? "Edit" : "Add"} Participant
            </DialogTitle>
            <DialogDescription>
              Configure a local participant and its role.
            </DialogDescription>
          </DialogHeader>
          {editing && (
            <form onSubmit={saveParticipant}>
              <div className="grid gap-4 sm:grid-cols-2">
                <Field
                  label="Participant Name"
                  required
                  value={editing.name}
                  onChange={(event) =>
                    setEditing({ ...editing, name: event.target.value })
                  }
                />
                <SelectField
                  label="Role"
                  value={editing.role}
                  options={[
                    "Operator",
                    "Investor",
                    "Site Manager",
                    "Building Management",
                  ]}
                  onChange={(event) =>
                    setEditing({
                      ...editing,
                      role: event.target.value as Participant["role"],
                    })
                  }
                />
                <Field
                  label="Investor Group"
                  value={editing.group}
                  disabled={editing.role !== "Investor"}
                  onChange={(event) =>
                    setEditing({ ...editing, group: event.target.value })
                  }
                />
                <Field
                  label="Priority"
                  type="number"
                  min={0}
                  required
                  value={editing.priority}
                  onChange={(event) =>
                    setEditing({
                      ...editing,
                      priority: Number(event.target.value),
                    })
                  }
                />
                <label className="flex gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={editing.active}
                    onChange={(event) =>
                      setEditing({ ...editing, active: event.target.checked })
                    }
                  />
                  Active
                </label>
                <label className="flex gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={editing.representative}
                    onChange={(event) =>
                      setEditing({
                        ...editing,
                        representative: event.target.checked,
                      })
                    }
                  />
                  Representative
                </label>
              </div>
              {error && (
                <p role="alert" className="mt-4 text-sm text-destructive">
                  {error}
                </p>
              )}
              <DialogFooter className="mt-6">
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => setEditing(null)}
                >
                  Cancel
                </Button>
                <Button>Save Participant</Button>
              </DialogFooter>
            </form>
          )}
        </DialogContent>
      </Dialog>
      <Dialog
        open={!!term}
        onOpenChange={(open) => {
          if (!open) setTerm(null);
        }}
      >
        <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
          <DialogHeader>
            <DialogTitle>
              {term?.value.id ? "Edit" : "Add"} Contract Term
            </DialogTitle>
            <DialogDescription>
              Configure payment terms for{" "}
              {participants.find((row) => row.id === term?.participantId)?.name}
              .
            </DialogDescription>
          </DialogHeader>
          {term && (
            <form onSubmit={saveTerm}>
              <div className="grid gap-4 sm:grid-cols-2">
                <SelectField
                  label="Contract Type"
                  value={term.value.type}
                  options={contractTypes.map((value) => ({
                    value,
                    label: contractTypeLabels[value],
                  }))}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: {
                        ...term.value,
                        type: event.target.value as ContractTerm["type"],
                      },
                    })
                  }
                />
                <SelectField
                  label="Payment Frequency"
                  value={term.value.frequency}
                  options={["MONTHLY", "YEARLY", "ONCE", "CUSTOM_PERIOD"]}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: {
                        ...term.value,
                        frequency: event.target
                          .value as ContractTerm["frequency"],
                      },
                    })
                  }
                />
                {term.value.type === "FIXED_COST" ? (
                  <Field
                    label="Fixed Amount"
                    type="number"
                    min={0}
                    required
                    value={term.value.fixed}
                    onChange={(event) =>
                      setTerm({
                        ...term,
                        value: {
                          ...term.value,
                          fixed: Number(event.target.value),
                        },
                      })
                    }
                  />
                ) : (
                  <Field
                    label="Share Percent"
                    type="number"
                    min={0}
                    max={100}
                    step="0.01"
                    required
                    value={term.value.share}
                    onChange={(event) =>
                      setTerm({
                        ...term,
                        value: {
                          ...term.value,
                          share: Number(event.target.value),
                        },
                      })
                    }
                  />
                )}
                <Field
                  label="Payment Due Day"
                  type="number"
                  min={1}
                  max={31}
                  required
                  value={term.value.dueDay}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: {
                        ...term.value,
                        dueDay: Number(event.target.value),
                      },
                    })
                  }
                />
                <Field
                  label="Valid From"
                  type="date"
                  required
                  value={term.value.validFrom}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: { ...term.value, validFrom: event.target.value },
                    })
                  }
                />
                <Field
                  label="Valid To (Optional)"
                  type="date"
                  min={term.value.validFrom}
                  value={term.value.validTo}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: { ...term.value, validTo: event.target.value },
                    })
                  }
                />
                <Field
                  label="Min Guarantee Amount"
                  type="number"
                  min={0}
                  value={term.value.minimum}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: {
                        ...term.value,
                        minimum: Number(event.target.value),
                      },
                    })
                  }
                />
                <Field
                  label="Cap Amount (0 = no cap)"
                  type="number"
                  min={0}
                  value={term.value.cap}
                  onChange={(event) =>
                    setTerm({
                      ...term,
                      value: { ...term.value, cap: Number(event.target.value) },
                    })
                  }
                />
              </div>
              {error && (
                <p role="alert" className="mt-4 text-sm text-destructive">
                  {error}
                </p>
              )}
              <DialogFooter className="mt-6">
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => setTerm(null)}
                >
                  Cancel
                </Button>
                <Button>Save Term</Button>
              </DialogFooter>
            </form>
          )}
        </DialogContent>
      </Dialog>
      <Dialog
        open={!!deleting}
        onOpenChange={(open) => {
          if (!open) setDeleting(null);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              Delete {deleting?.termId ? "Term" : "Participant"}
            </DialogTitle>
            <DialogDescription>
              Remove this{" "}
              {deleting?.termId ? "term" : "participant and all their terms"}{" "}
              from the local contract?
            </DialogDescription>
          </DialogHeader>
          <PreviewNotice>
            Existing settlement snapshots are preserved.
          </PreviewNotice>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleting(null)}>
              Cancel
            </Button>
            <Button
              variant="destructive"
              onClick={() => {
                onChange(
                  deleting?.termId
                    ? participants.map((row) =>
                        row.id === deleting.participantId
                          ? {
                              ...row,
                              terms: row.terms.filter(
                                (item) => item.id !== deleting.termId,
                              ),
                            }
                          : row,
                      )
                    : participants.filter(
                        (row) => row.id !== deleting?.participantId,
                      ),
                );
                setDeleting(null);
              }}
            >
              Delete Preview
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
