import { useState } from "react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import { Textarea } from "@/components/ui/textarea";

import { ChipQuestion } from "./components/chip-question";
import { LabeledField } from "./components/field-label";
import { ScreenshotUpload } from "./components/screenshot-upload";
import { TYPE_META } from "./display-meta";
import type { FeedbackType } from "./types";

/**
 * Request type — derived from `TYPE_META` so the chips stay in sync with the
 * card's TypeBadge (Idea / Enhancement / Bug). Single-select.
 */
const TYPE_OPTIONS = (Object.keys(TYPE_META) as FeedbackType[]).map((t) => ({
  value: t,
  label: TYPE_META[t].label,
}));

/** Sentinel for the "Other" area — only offered for ideas (see below). */
const OTHER_AREA = "__other__";

/**
 * Backoffice features a request can relate to — mirrors the Backoffice sidebar
 * navigation. Shown as a dropdown.
 */
const AREA_OPTIONS = [
  { value: "Contacts", label: "Clients" },
  { value: "Companies", label: "Companies" },
  { value: "Loan CRM", label: "Loan CRM" },
  { value: "Conversations", label: "Conversations" },
  { value: "Appointments", label: "Appointments" },
  { value: "WealthX AI", label: "WealthX AI" },
  { value: "Resource Centre", label: "Resource Centre" },
  { value: "Staff", label: "Staff" },
  { value: "Web Pages", label: "Web Pages" },
  { value: "Account", label: "Account" },
];

/* ---- Bug questions: the signals a triager needs to reproduce + rank it ---- */
const BUG_FREQUENCY_OPTIONS = [
  { value: "every-time", label: "Every time" },
  { value: "sometimes", label: "Sometimes" },
  { value: "once", label: "Only once" },
];

const BUG_IMPACT_OPTIONS = [
  { value: "blocked", label: "I'm blocked" },
  { value: "workaround", label: "I have a workaround" },
  { value: "minor", label: "Minor annoyance" },
];

/* ---- Idea / enhancement questions: the demand + value signals ---- */
const BENEFICIARY_OPTIONS = [
  { value: "me", label: "Me" },
  { value: "team", label: "My team" },
  { value: "clients", label: "My clients" },
];

export interface FeedbackNewRequestPayload {
  title: string;
  type: FeedbackType;
  area: string;
  problemStatement: string;
  stepsToReproduce?: string;
  frequency?: string;
  impact?: string;
  proposedSolution?: string;
  workaround?: string;
  beneficiaries?: string[];
  previewImage?: File | null;
}

export interface FeedbackNewRequestProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /**
   * Fired when the user submits the intake form. May return a promise — the form
   * awaits it and keeps the submit button busy until it settles. On success the
   * host closes the drawer; if it rejects, the form stays open and `onError`
   * fires. The form never closes on its own.
   */
  onSubmit?: (payload: FeedbackNewRequestPayload) => void | Promise<void>;
  /**
   * Fired when `onSubmit` rejects. The drawer stays open so the user can retry —
   * the host decides how (or whether) to surface the failure.
   */
  onError?: (error: unknown) => void;
}

/**
 * Broker-facing intake form, presented as a right-side slide-out. The follow-up
 * questions adapt to the request type: a **bug** asks for reproduction +
 * frequency + impact, while an **idea / enhancement** asks for the desired
 * outcome, the current workaround, and who it benefits.
 */
export function FeedbackNewRequest({
  open,
  onOpenChange,
  onSubmit,
  onError,
}: FeedbackNewRequestProps) {
  const [title, setTitle] = useState("");
  const [type, setType] = useState("");
  const [area, setArea] = useState("");
  const [otherArea, setOtherArea] = useState("");
  const [problem, setProblem] = useState("");
  // Bug-specific
  const [steps, setSteps] = useState("");
  const [bugFrequency, setBugFrequency] = useState("");
  const [bugImpact, setBugImpact] = useState("");
  // Idea / enhancement-specific
  const [outcome, setOutcome] = useState("");
  const [workaround, setWorkaround] = useState("");
  const [beneficiaries, setBeneficiaries] = useState<string[]>([]);
  const [screenshot, setScreenshot] = useState<File | null>(null);
  // In-flight while the host resolves the submission — blocks double-submits.
  const [submitting, setSubmitting] = useState(false);

  const isBug = type === "bug";
  const isImprovement = type === "idea" || type === "enhancement";

  // "Other" area is an escape hatch for ideas that don't map to an existing
  // Backoffice feature — only offered when the request is an idea.
  const areaOptions =
    type === "idea"
      ? [...AREA_OPTIONS, { value: OTHER_AREA, label: "Other (not listed)" }]
      : AREA_OPTIONS;

  function handleTypeChange(next: string) {
    setType(next);
    // Drop the "Other" selection if it's no longer offered for this type.
    if (next !== "idea" && area === OTHER_AREA) {
      setArea("");
      setOtherArea("");
    }
  }

  const resolvedArea = area === OTHER_AREA ? otherArea.trim() : area;
  const areaComplete =
    area !== "" && (area !== OTHER_AREA || otherArea.trim() !== "");
  const canSubmit =
    title.trim() !== "" &&
    Boolean(type) &&
    areaComplete &&
    problem.trim() !== "";

  const buildPayload = (): FeedbackNewRequestPayload => {
    const payload: FeedbackNewRequestPayload = {
      title: title.trim(),
      type: type as FeedbackType,
      area: resolvedArea,
      problemStatement: problem.trim(),
    };
    if (isBug) {
      if (steps.trim()) payload.stepsToReproduce = steps.trim();
      if (bugFrequency) {
        const match = BUG_FREQUENCY_OPTIONS.find((o) => o.value === bugFrequency);
        payload.frequency = match?.label ?? bugFrequency;
      }
      if (bugImpact) {
        const match = BUG_IMPACT_OPTIONS.find((o) => o.value === bugImpact);
        payload.impact = match?.label ?? bugImpact;
      }
    }
    if (isImprovement) {
      if (outcome.trim()) payload.proposedSolution = outcome.trim();
      if (workaround.trim()) payload.workaround = workaround.trim();
      if (beneficiaries.length > 0) {
        payload.beneficiaries = beneficiaries.map((v) => {
          const match = BENEFICIARY_OPTIONS.find((o) => o.value === v);
          return match?.label ?? v;
        });
      }
    }
    if (screenshot) payload.previewImage = screenshot;
    return payload;
  };

  // Forward the payload and await the host. On success the host closes the
  // drawer; on failure we emit `onError` and stay open (we never close
  // ourselves), so the user can retry. Catching also keeps the rejection from
  // going unhandled.
  async function handleSubmit() {
    if (submitting) return;
    setSubmitting(true);
    try {
      await onSubmit?.(buildPayload());
    } catch (error) {
      onError?.(error);
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent side="right" className="flex w-full flex-col sm:max-w-xl">
        <SheetHeader>
          <SheetTitle className="text-h5">New request</SheetTitle>
          <SheetDescription>
            Tell us what&apos;s going on. The more detail you give, the faster
            we can act on it.
          </SheetDescription>
        </SheetHeader>

        <div className="flex flex-1 flex-col gap-6 overflow-auto px-4">
          <LabeledField label="Title" htmlFor="title" required>
            <Input
              id="title"
              placeholder="A short, descriptive summary"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
            />
          </LabeledField>

          <ChipQuestion
            label="What type of request is this?"
            required
            options={TYPE_OPTIONS}
            value={type}
            onValueChange={(v) => handleTypeChange(v as string)}
          />

          <LabeledField
            label="Which area does it relate to?"
            htmlFor="area"
            required
          >
            <Select
              value={area}
              onValueChange={(v) => setArea(v as string)}
              items={areaOptions}
            >
              <SelectTrigger id="area" className="w-full">
                <SelectValue placeholder="Select a Backoffice feature" />
              </SelectTrigger>
              <SelectContent>
                {areaOptions.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            {/* Ideas may not map to an existing feature — let them describe it. */}
            {area === OTHER_AREA && (
              <Input
                placeholder="Describe the area or feature this idea relates to"
                value={otherArea}
                onChange={(e) => setOtherArea(e.target.value)}
              />
            )}
          </LabeledField>

          {/* ---- Bug: reproduce + rank ---- */}
          {isBug && (
            <>
              <LabeledField label="What went wrong?" htmlFor="problem" required>
                <Textarea
                  id="problem"
                  rows={3}
                  placeholder="What happened, and what did you expect to happen instead?"
                  value={problem}
                  onChange={(e) => setProblem(e.target.value)}
                />
              </LabeledField>

              <LabeledField label="Steps to reproduce" htmlFor="steps" optional>
                <Textarea
                  id="steps"
                  rows={3}
                  placeholder={"1. Go to…\n2. Click…\n3. See…"}
                  value={steps}
                  onChange={(e) => setSteps(e.target.value)}
                />
              </LabeledField>

              <ChipQuestion
                label="How often does it happen?"
                options={BUG_FREQUENCY_OPTIONS}
                value={bugFrequency}
                onValueChange={(v) => setBugFrequency(v as string)}
              />

              <ChipQuestion
                label="How much does it block you?"
                options={BUG_IMPACT_OPTIONS}
                value={bugImpact}
                onValueChange={(v) => setBugImpact(v as string)}
              />
            </>
          )}

          {/* ---- Idea / enhancement: outcome + demand ---- */}
          {isImprovement && (
            <>
              <LabeledField label="Description" htmlFor="problem" required>
                <Textarea
                  id="problem"
                  rows={3}
                  placeholder="What are you trying to do, and what gets in the way today?"
                  value={problem}
                  onChange={(e) => setProblem(e.target.value)}
                />
              </LabeledField>

              <LabeledField
                label="What would the ideal outcome look like?"
                htmlFor="outcome"
                optional
              >
                <Textarea
                  id="outcome"
                  rows={3}
                  placeholder="Describe how it should work for you."
                  value={outcome}
                  onChange={(e) => setOutcome(e.target.value)}
                />
              </LabeledField>

              <LabeledField
                label="How do you handle this today?"
                htmlFor="workaround"
                optional
              >
                <Textarea
                  id="workaround"
                  rows={2}
                  placeholder="Your current workaround, if any."
                  value={workaround}
                  onChange={(e) => setWorkaround(e.target.value)}
                />
              </LabeledField>

              <ChipQuestion
                label="Who would benefit?"
                hint="Pick all that apply."
                multiple
                options={BENEFICIARY_OPTIONS}
                value={beneficiaries}
                onValueChange={(v) => setBeneficiaries(v as string[])}
              />
            </>
          )}

          <LabeledField label="Add a screenshot" optional>
            <ScreenshotUpload onFileChange={setScreenshot} />
          </LabeledField>
        </div>

        <SheetFooter className="flex-row justify-end gap-2 border-t">
          <SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
          <Button onClick={handleSubmit} disabled={!canSubmit || submitting}>
            {submitting ? "Submitting…" : "Submit request"}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}
