"use client";

import type { ChangeEvent, ComponentType } from "react";
import Image from "next/image";
import {
  Bug,
  Check,
  CheckCircle2,
  CreditCard,
  ImagePlus,
  Lightbulb,
  MessageCircleMore,
  Send,
  Trash2,
} from "lucide-react";

import { BackButton } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import type { FeedbackCategory } from "@/data/schemas/feedback";
import {
  resolveGlobalRouteContext,
  type GlobalReturnToValue,
} from "@/router/global-route-context";
import { useGlobalAppNavigator } from "@/router/use-global-app-navigator";

import {
  FEEDBACK_IMAGE_ACCEPT,
  FEEDBACK_IMAGE_LIMIT,
} from "./feedback-image";
import {
  FEEDBACK_CONTENT_MIN_LENGTH,
  FEEDBACK_CONTENT_MAX_LENGTH,
  useFeedbackSubmission,
} from "./use-feedback-submission";

import styles from "./feedback-screen.module.css";

interface CategoryOption {
  value: FeedbackCategory;
  label: string;
  icon: ComponentType<{ size?: number; strokeWidth?: number }>;
}

const CATEGORY_OPTIONS: readonly CategoryOption[] = [
  { value: "problem", label: "Problem", icon: Bug },
  { value: "suggestion", label: "Suggestion", icon: Lightbulb },
  { value: "payment", label: "Payment", icon: CreditCard },
  { value: "other", label: "Other", icon: MessageCircleMore },
];

export interface FeedbackScreenProps {
  returnTo?: GlobalReturnToValue;
}

export function FeedbackScreen({ returnTo }: FeedbackScreenProps) {
  const navigator = useGlobalAppNavigator();
  const navigation = resolveGlobalRouteContext(returnTo);
  const form = useFeedbackSubmission();

  if (form.feedbackId) {
    return (
      <MobileShell background="#f8f6f4">
        <main className={styles.successShell}>
          <div className={styles.successGlow} aria-hidden="true" />
          <section className={styles.successCard} aria-live="polite">
            <span className={styles.successIcon} aria-hidden="true">
              <CheckCircle2 size={36} strokeWidth={1.9} />
            </span>
            <p className={styles.successEyebrow}>Feedback received</p>
            <h1 className={styles.successTitle}>Thank you for helping us.</h1>
            <p className={styles.successCopy}>
              Your report is safely on its way to the CozSweet team.
            </p>
            <div className={styles.feedbackIdBlock}>
              <span>Feedback ID</span>
              <strong>{form.feedbackId}</strong>
            </div>
            <button
              type="button"
              data-analytics-key="feedback.back_to_sidebar"
              className={styles.primaryButton}
              onClick={() => navigator.replace(navigation.sidebarUrl)}
            >
              Back to Sidebar
            </button>
          </section>
        </main>
      </MobileShell>
    );
  }

  const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
    if (event.target.files) void form.addImages(event.target.files);
    event.target.value = "";
  };

  return (
    <MobileShell background="#f8f6f4">
      <main className={styles.shell}>
        <div className={styles.glowOne} aria-hidden="true" />
        <div className={styles.glowTwo} aria-hidden="true" />

        <header className={styles.header}>
          <BackButton
            href={navigation.sidebarUrl}
            variant="soft"
            ariaLabel="Back to sidebar"
            analyticsKey="feedback.back_to_sidebar"
          />
          <div className={styles.headingBlock}>
            <h1 className={styles.title}>Help us improve CozSweet</h1>
            <p className={styles.subtitle}>
              Tell us what happened. Screenshots help us understand it faster.
            </p>
          </div>
        </header>

        <form className={styles.form} onSubmit={form.submit} noValidate>
          <fieldset className={styles.fieldset}>
            <legend className={styles.fieldLabel}>What is this about?</legend>
            <div className={styles.categoryGrid}>
              {CATEGORY_OPTIONS.map((option) => {
                const Icon = option.icon;
                const selected = form.category === option.value;
                return (
                  <label
                    key={option.value}
                    className={`${styles.categoryCard} ${selected ? styles.categoryCardSelected : ""}`}
                  >
                    <input
                      type="radio"
                      name="feedback-category"
                      value={option.value}
                      checked={selected}
                      disabled={form.isSubmitting}
                      className={styles.visuallyHidden}
                      onChange={() => form.setCategory(option.value)}
                    />
                    <Icon size={18} strokeWidth={2} />
                    <span>{option.label}</span>
                    {selected ? (
                      <Check className={styles.categoryCheck} size={14} />
                    ) : null}
                  </label>
                );
              })}
            </div>
          </fieldset>

          <div className={styles.fieldGroup}>
            <label className={styles.fieldLabel} htmlFor="feedback-content">
              Describe your feedback
            </label>
            <p id="feedback-content-hint" className={styles.contentHint}>
              Minimum {FEEDBACK_CONTENT_MIN_LENGTH} characters required.
            </p>
            <div className={styles.textareaFrame}>
              <textarea
                id="feedback-content"
                aria-describedby="feedback-content-hint"
                value={form.content}
                maxLength={FEEDBACK_CONTENT_MAX_LENGTH}
                disabled={form.isSubmitting}
                className={styles.textarea}
                placeholder="What happened, and what did you expect?"
                onChange={(event) => form.setContent(event.target.value)}
              />
              <span className={styles.characterCount}>
                {form.content.length}/{FEEDBACK_CONTENT_MAX_LENGTH}
              </span>
            </div>
          </div>

          <section className={styles.fieldGroup} aria-labelledby="feedback-images-label">
            <div className={styles.imageHeading}>
              <div>
                <h2 id="feedback-images-label" className={styles.fieldLabel}>
                  Add screenshots <span>Optional</span>
                </h2>
                <p className={styles.fieldHint}>JPEG, PNG or WebP · up to 5 MB each</p>
              </div>
              <span className={styles.imageCount}>
                {form.images.length}/{FEEDBACK_IMAGE_LIMIT}
              </span>
            </div>

            <div className={styles.imageGrid}>
              {form.images.map((image, index) => (
                <div className={styles.imagePreview} key={image.id}>
                  <Image
                    src={image.previewUrl}
                    alt={`Feedback screenshot ${index + 1}`}
                    fill
                    unoptimized
                    sizes="120px"
                    className={styles.previewImage}
                  />
                  <button
                    type="button"
                    className={styles.removeImageButton}
                    disabled={form.isSubmitting}
                    aria-label={`Remove screenshot ${index + 1}`}
                    onClick={() => form.removeImage(image.id)}
                  >
                    <Trash2 size={15} />
                  </button>
                </div>
              ))}

              {form.images.length < FEEDBACK_IMAGE_LIMIT ? (
                <label
                  className={`${styles.addImageButton} ${form.isPreparingImages ? styles.addImageButtonBusy : ""}`}
                >
                  <input
                    type="file"
                    multiple
                    accept={FEEDBACK_IMAGE_ACCEPT}
                    disabled={form.isPreparingImages || form.isSubmitting}
                    className={styles.visuallyHidden}
                    onChange={handleImageChange}
                  />
                  <ImagePlus size={23} strokeWidth={1.8} />
                  <span>{form.isPreparingImages ? "Preparing..." : "Add image"}</span>
                </label>
              ) : null}
            </div>
          </section>

          <div className={styles.statusSlot} aria-live="polite">
            {form.errorMessage ? (
              <p className={styles.errorMessage} role="alert">
                {form.errorMessage}
              </p>
            ) : null}
          </div>

          <button
            type="submit"
            data-analytics-key="feedback.submit"
            data-analytics-label="Submit feedback"
            className={styles.primaryButton}
            disabled={!form.canSubmit}
          >
            <Send size={18} strokeWidth={2.1} aria-hidden="true" />
            <span>{form.isSubmitting ? "Sending feedback..." : "Send feedback"}</span>
          </button>
        </form>
      </main>
    </MobileShell>
  );
}
