"use client";

import { useReducer, useRef } from "react";
import NextImage from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { uploadProductImage, deleteProductImage } from "@/actions/products/upload-image";
import { updateProduct } from "@/actions/products/update-product";
import { AdminInput,  AdminTextInput, AdminTextarea, AdminSelect  } from "./design-system/AdminFormElements";

async function resizeImage(file: File, maxWidth: number): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      let { width, height } = img;
      if (width > maxWidth) {
        height = Math.round(height * (maxWidth / width));
        width = maxWidth;
      }
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext("2d")!;
      ctx.drawImage(img, 0, 0, width, height);
      canvas.toBlob((blob) => {
        if (!blob) {
          reject(new Error("Failed to resize image"));
          return;
        }
        blob.arrayBuffer().then((buf) => resolve(buf));
      }, "image/jpeg", 0.85);
    };
    img.onerror = reject;
    img.src = URL.createObjectURL(file);
  });
}

type Brand = {
  id: string;
  name: string;
  slug: string;
};

type ProductEditFormProps = {
  product: {
    id: string;
    name: string;
    description: string;
    price: number;
    type: string;
    active: boolean;
    brand_id: string;
    image_url?: string | null;
    is_taxable?: boolean;
    pickup_type?: string;
  };
  brands: Brand[];
};

type Draft = {
  name?: string;
  description?: string;
  price?: number;
  type?: string;
  active?: boolean;
  brand_id?: string;
  image_url?: string;
  is_taxable?: boolean;
  pickup_type?: string;
};

type State = {
  draft: Draft;
  saving: boolean;
  error: string | null;
  saved: boolean;
  dragOver: boolean;
  uploading: boolean;
  uploadError: string | null;
  imagePreview: string | null;
};

type Action =
  | { type: "SET_DRAFT_FIELD"; field: "name"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "description"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "type"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "brand_id"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "image_url"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "pickup_type"; value: string }
  | { type: "SET_DRAFT_FIELD"; field: "price"; value: number }
  | { type: "SET_DRAFT_FIELD"; field: "active"; value: boolean }
  | { type: "SET_DRAFT_FIELD"; field: "is_taxable"; value: boolean }
  | { type: "SET_SAVING"; value: boolean }
  | { type: "SET_ERROR"; value: string | null }
  | { type: "SET_SAVED"; value: boolean }
  | { type: "SET_DRAG_OVER"; value: boolean }
  | { type: "SET_UPLOADING"; value: boolean }
  | { type: "SET_UPLOAD_ERROR"; value: string | null }
  | { type: "SET_IMAGE_PREVIEW"; value: string | null };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_DRAFT_FIELD":
      return { ...state, draft: { ...state.draft, [action.field]: action.value } };
    case "SET_SAVING":
      return { ...state, saving: action.value };
    case "SET_ERROR":
      return { ...state, error: action.value };
    case "SET_SAVED":
      return { ...state, saved: action.value };
    case "SET_DRAG_OVER":
      return { ...state, dragOver: action.value };
    case "SET_UPLOADING":
      return { ...state, uploading: action.value };
    case "SET_UPLOAD_ERROR":
      return { ...state, uploadError: action.value };
    case "SET_IMAGE_PREVIEW":
      return { ...state, imagePreview: action.value };
    default:
      return state;
  }
}

export default function ProductEditForm({ product, brands }: ProductEditFormProps) {
  const router = useRouter();
  const [state, dispatch] = useReducer(reducer, undefined, () => ({
    draft: {},
    saving: false,
    error: null,
    saved: false,
    dragOver: false,
    uploading: false,
    uploadError: null,
    imagePreview: product.image_url ?? null,
  }));

  const fileInputRef = useRef<HTMLInputElement>(null);

  // Derived effective values from draft overrides + product prop
  const name = state.draft.name ?? product.name;
  const description = state.draft.description ?? product.description;
  const price = state.draft.price ?? product.price;
  const type = state.draft.type ?? product.type;
  const active = state.draft.active ?? product.active;
  const brand_id = state.draft.brand_id ?? product.brand_id;
  const image_url = state.draft.image_url ?? product.image_url ?? "";
  const is_taxable = state.draft.is_taxable ?? product.is_taxable ?? true;
  const pickup_type = state.draft.pickup_type ?? product.pickup_type ?? "scheduled_stop";

  async function handleFileSelect(file: File) {
    const validTypes = ["image/png", "image/jpeg", "image/webp"];
    if (!validTypes.includes(file.type)) {
      dispatch({ type: "SET_UPLOAD_ERROR", value: "Only PNG, JPEG, and WebP images are allowed." });
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      dispatch({ type: "SET_UPLOAD_ERROR", value: "Image must be under 5MB." });
      return;
    }

    // Client-side resize to max 1200px width
    const resizedBuffer = await resizeImage(file, 1200);
    const resizedFile = new File([resizedBuffer], file.name, { type: "image/jpeg" });

    dispatch({ type: "SET_UPLOAD_ERROR", value: null });
    dispatch({ type: "SET_UPLOADING", value: true });
    const result = await uploadProductImage(product.id, resizedFile);
    dispatch({ type: "SET_UPLOADING", value: false });

    if (result.success) {
      dispatch({ type: "SET_DRAFT_FIELD", field: "image_url", value: result.imageUrl });
      dispatch({ type: "SET_IMAGE_PREVIEW", value: result.imageUrl });
    } else {
      dispatch({ type: "SET_UPLOAD_ERROR", value: result.error ?? "Upload failed." });
    }
  }

  async function handleRemoveImage() {
    const result = await deleteProductImage(product.id);
    if (result.success) {
      dispatch({ type: "SET_DRAFT_FIELD", field: "image_url", value: "" });
      dispatch({ type: "SET_IMAGE_PREVIEW", value: null });
    }
  }

  async function handleSave() {
    if (!name.trim()) {
      dispatch({ type: "SET_ERROR", value: "Product name is required." });
      return;
    }
    dispatch({ type: "SET_SAVING", value: true });
    dispatch({ type: "SET_ERROR", value: null });
    dispatch({ type: "SET_SAVED", value: false });

    const result = await updateProduct(product.id, brand_id, {
      name,
      description,
      price: Number(price),
      type,
      active,
      image_url: image_url || null,
      is_taxable,
      pickup_type,
    });

    if (!result.success) {
      dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to save" });
      dispatch({ type: "SET_SAVING", value: false });
      return;
    }

    dispatch({ type: "SET_SAVED", value: true });
    dispatch({ type: "SET_SAVING", value: false });
    router.refresh();
  }

  return (
    <div className="space-y-6">
      {state.error && (
        <div className="rounded-xl bg-[var(--admin-danger-soft)] border border-[var(--admin-danger)] p-4 text-sm text-[var(--admin-danger)]">
          {state.error}
        </div>
      )}

      {state.saved && (
        <div className="rounded-xl bg-[var(--admin-primary-soft)] border border-[var(--admin-primary)] p-4 text-sm text-[var(--admin-primary)]">
          Product updated successfully.
        </div>
      )}

      <BasicInfoSection
        name={name}
        description={description}
        dispatch={dispatch}
      />

      <PricingSection
        price={price}
        type={type}
        dispatch={dispatch}
      />

      <BrandSection
        brand_id={brand_id}
        brands={brands}
        dispatch={dispatch}
      />

      <StatusTogglesSection
        active={active}
        is_taxable={is_taxable}
        dispatch={dispatch}
      />

      <PickupTypeSection
        pickup_type={pickup_type}
        dispatch={dispatch}
      />

      <ProductImageSection
        uploading={state.uploading}
        uploadError={state.uploadError}
        imagePreview={state.imagePreview}
        dragOver={state.dragOver}
        fileInputRef={fileInputRef}
        onFileSelect={handleFileSelect}
        onRemoveImage={handleRemoveImage}
      />

      <ProductFormActions saving={state.saving} onSave={handleSave} />
    </div>
  );
}

function BasicInfoSection({
  name,
  description,
  dispatch,
}: {
  name: string;
  description: string;
  dispatch: React.Dispatch<Action>;
}) {
  return (
    <>
      <AdminInput label="Name">
        <AdminTextInput
          value={name}
          onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "name", value: e.target.value })}
          placeholder="Product name"
        />
      </AdminInput>

      <AdminInput label="Description">
        <AdminTextarea
          value={description}
          onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "description", value: e.target.value })}
          rows={3}
          placeholder="Product description"
        />
      </AdminInput>
    </>
  );
}

function PricingSection({
  price,
  type,
  dispatch,
}: {
  price: number;
  type: string;
  dispatch: React.Dispatch<Action>;
}) {
  return (
    <div className="grid grid-cols-2 gap-4">
      <AdminInput label="Price">
          <AdminTextInput
            type="number"
            step="0.01"
            min="0"
            value={price}
            onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "price", value: Number(e.target.value) })}
            placeholder="0.00"
          />
        </AdminInput>

      <AdminInput label="Type">
          <AdminTextInput
            value={type}
            onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "type", value: e.target.value })}
            placeholder="e.g. Sweet Corn"
          />
        </AdminInput>
    </div>
  );
}

function BrandSection({
  brand_id,
  brands,
  dispatch,
}: {
  brand_id: string;
  brands: Brand[];
  dispatch: React.Dispatch<Action>;
}) {
  return (
    <AdminInput label="Brand">
      <AdminSelect
        value={brand_id}
        onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "brand_id", value: e.target.value })}
        options={brands.map((b) => ({ value: b.id, label: b.name }))}
      />
    </AdminInput>
  );
}

function StatusTogglesSection({
  active,
  is_taxable,
  dispatch,
}: {
  active: boolean;
  is_taxable: boolean;
  dispatch: React.Dispatch<Action>;
}) {
  return (
    <>
      <div>
        <label className="mb-2 block text-sm font-medium text-[var(--admin-text-primary)]">
          <span className="block mb-2">Status</span>
          <button type="button"
            onClick={() => dispatch({ type: "SET_DRAFT_FIELD", field: "active", value: !active })}
            className={`w-full rounded-xl px-4 py-3 text-sm font-medium transition-colors ${
              active
                ? "bg-[var(--admin-primary-soft)] text-[var(--admin-primary)] ring-1 ring-[var(--admin-primary)]"
                : "bg-[var(--admin-bg)] text-[var(--admin-text-muted)] hover:bg-[var(--admin-bg-subtle)]"
            }`}
          >
            {active ? "Active" : "Inactive"}
          </button>
        </label>
      </div>

      <div>
        <label className="mb-2 block text-sm font-medium text-[var(--admin-text-primary)]">
          <span className="block mb-2">Taxable</span>
          <button type="button"
            onClick={() => dispatch({ type: "SET_DRAFT_FIELD", field: "is_taxable", value: !is_taxable })}
            className={`w-full rounded-xl px-4 py-3 text-sm font-medium transition-colors flex items-center gap-3 ${
              is_taxable
                ? "bg-[var(--admin-primary-soft)] text-[var(--admin-primary)] ring-1 ring-[var(--admin-primary)]"
                : "bg-[var(--admin-accent-soft)] text-[var(--admin-accent)] ring-1 ring-[var(--admin-accent)]"
            }`}
          >
            <span className="text-lg" aria-hidden="true">{is_taxable ? "✓" : "✗"}</span>
            <span>{is_taxable ? "Taxable — tax applied at checkout for nexus shipments" : "Non-taxable — always exempt from sales tax"}</span>
          </button>
        </label>
        <p className="mt-1.5 text-xs text-[var(--admin-text-muted)]">Tax is calculated at checkout for shipping orders in your brand&apos;s nexus states. Non-taxable items (e.g. cooler boxes, apparel) are always exempt.</p>
      </div>
    </>
  );
}

function PickupTypeSection({
  pickup_type,
  dispatch,
}: {
  pickup_type: string;
  dispatch: React.Dispatch<Action>;
}) {
  return (
    <AdminInput 
          label="Pickup Type"
          helpText="Shed pickup uses the product description as the pickup location — no stop required at checkout."
        >
          <AdminSelect
            value={pickup_type}
            onChange={(e) => dispatch({ type: "SET_DRAFT_FIELD", field: "pickup_type", value: e.target.value })}
            options={[
              { value: "scheduled_stop", label: "Scheduled Stop — requires stop selection at checkout" },
              { value: "shed", label: "Shed Pickup — uses description as location" },
            ]}
          />
        </AdminInput>
  );
}

function ProductImageSection({
  uploading,
  uploadError,
  imagePreview,
  dragOver,
  fileInputRef,
  onFileSelect,
  onRemoveImage,
}: {
  uploading: boolean;
  uploadError: string | null;
  imagePreview: string | null;
  dragOver: boolean;
  fileInputRef: React.RefObject<HTMLInputElement | null>;
  onFileSelect: (file: File) => void;
  onRemoveImage: () => void;
}) {
  return (
    <div>
      <span className="mb-1 block text-sm font-medium text-[var(--admin-text-primary)]">Product Image</span>
      <p className="text-xs text-[var(--admin-text-muted)] mb-2">JPG, PNG, WebP · 1200px max width · max 5MB (ideally under 2MB)</p>

      <label
        onDragOver={(e) => e.preventDefault()}
        onDrop={(e) => {
          e.preventDefault();
          const file = e.dataTransfer.files[0];
          if (file) onFileSelect(file);
        }}
        className={`
          flex flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed p-6 cursor-pointer transition-colors
          ${dragOver ? "border-[var(--admin-primary)] bg-[var(--admin-primary-soft)]" : "border-[var(--admin-border)] hover:border-[var(--admin-primary)] hover:bg-[var(--admin-bg)]"}
          ${uploading ? "opacity-50 pointer-events-none" : ""}
        `}
      >
        {uploading ? (
          <>
            <div className="h-5 w-5 rounded-full border-2 border-[var(--admin-text-muted)] border-t-transparent animate-spin" />
            <span className="text-sm text-[var(--admin-text-muted)]">Uploading...</span>
          </>
        ) : imagePreview ? (
          <>
            <span className="relative inline-block h-32 w-auto">
              <NextImage src={imagePreview} alt="Product preview" fill style={{ objectFit: "contain" }} className="rounded-lg" />
            </span>
            <span className="text-xs text-[var(--admin-text-muted)]">Click or drop to replace</span>
          </>
        ) : (
          <>
            <svg className="h-8 w-8 text-[var(--admin-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
            </svg>
            <span className="text-sm text-[var(--admin-text-muted)]">Drag & drop or click to upload</span>
          </>
        )}
        <input aria-label="File upload"
          ref={fileInputRef}
          type="file"
          accept="image/png,image/jpeg,image/webp"
          className="sr-only"
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) onFileSelect(file);
          }}
        />
      </label>

      {uploadError && <p className="mt-1 text-xs text-[var(--admin-danger)]">{uploadError}</p>}

      {imagePreview && (
        <button
          type="button"
          onClick={onRemoveImage}
          className="mt-2 text-xs text-[var(--admin-danger)] hover:underline"
        >
          Remove image
        </button>
      )}
    </div>
  );
}

function ProductFormActions({ saving, onSave }: { saving: boolean; onSave: () => void }) {
  return (
    <div className="flex items-center gap-3 pt-4 border-t border-[var(--admin-border-light)]">
      <button type="button"
        onClick={onSave}
        disabled={saving}
        className="ha-btn-primary"
      >
        {saving ? "Saving..." : "Save Changes"}
      </button>
      <Link
        href="/admin/products"
        className="ha-btn-ghost"
      >
        Cancel
      </Link>
    </div>
  );
}