"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
import { Loader2, X, Upload, Plus, AlertCircle } from "lucide-react";
import Image from "next/image";
import { toast } from "sonner";
import { LocationPicker } from "@/components/maps/location-picker";

const tourFormSchema = z.object({
  title: z.string().min(5, "Title must be at least 5 characters"),
  description: z.string().min(20, "Description must be at least 20 characters"),
  city: z.string().min(2, "City is required"),
  meetingPoint: z.string().optional(),
  meetingPointLat: z.number().optional(),
  meetingPointLng: z.number().optional(),
  durationMin: z.number().min(30, "Duration must be at least 30 minutes"),
  priceCents: z.number().min(0, "Price must be positive"),
  maxGuests: z.number().min(1, "At least 1 guest required").max(100),
  published: z.boolean().optional().default(false),
});

type TourFormData = z.infer<typeof tourFormSchema>;

interface TourFormProps {
  initialData?: TourFormData & { 
    id?: string;
    meetingPointLat?: number;
    meetingPointLng?: number;
  };
  initialIncluded?: string[];
  initialTags?: string[];
  mode?: "create" | "edit";
}

export default function TourForm({ 
  initialData, 
  initialIncluded = [],
  initialTags = [],
  mode = "create" 
}: TourFormProps) {
  const router = useRouter();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [includedItems, setIncludedItems] = useState<string[]>(initialIncluded);
  const [includedInput, setIncludedInput] = useState("");
  const [tags, setTags] = useState<string[]>(initialTags);
  const [tagInput, setTagInput] = useState("");
  const [images, setImages] = useState<File[]>([]);
  const [imagePreviews, setImagePreviews] = useState<string[]>([]);
  const [uploadingImages, setUploadingImages] = useState(false);

  const {
    register,
    handleSubmit,
    formState: { errors },
    watch,
    setValue,
  } = useForm({
    resolver: zodResolver(tourFormSchema),
    defaultValues: {
      title: initialData?.title || "",
      description: initialData?.description || "",
      city: initialData?.city || "Zurich",
      meetingPoint: initialData?.meetingPoint || "",
      meetingPointLat: initialData?.meetingPointLat,
      meetingPointLng: initialData?.meetingPointLng,
      durationMin: initialData?.durationMin || 180,
      priceCents: initialData?.priceCents || 5000,
      maxGuests: initialData?.maxGuests || 10,
      published: initialData?.published ?? false,
    },
  });

  const published = watch("published");
  const priceCents = watch("priceCents");

  const addIncludedItem = () => {
    if (includedInput.trim() && !includedItems.includes(includedInput.trim())) {
      setIncludedItems([...includedItems, includedInput.trim()]);
      setIncludedInput("");
    }
  };

  const removeIncludedItem = (item: string) => {
    setIncludedItems(includedItems.filter((i) => i !== item));
  };

  const addTag = () => {
    if (tagInput.trim() && !tags.includes(tagInput.trim().toLowerCase())) {
      setTags([...tags, tagInput.trim().toLowerCase()]);
      setTagInput("");
    }
  };

  const removeTag = (tag: string) => {
    setTags(tags.filter((t) => t !== tag));
  };

  const handleImageSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(e.target.files || []);
    const validFiles = files.filter((file) => {
      if (!file.type.startsWith("image/")) {
        return false;
      }
      if (file.size > 5 * 1024 * 1024) {
        // 5MB limit
        return false;
      }
      return true;
    });

    setImages((prev) => [...prev, ...validFiles]);

    // Create previews
    validFiles.forEach((file) => {
      const reader = new FileReader();
      reader.onloadend = () => {
        setImagePreviews((prev) => [...prev, reader.result as string]);
      };
      reader.readAsDataURL(file);
    });
  };

  const removeImage = (index: number) => {
    setImages((prev) => prev.filter((_, i) => i !== index));
    setImagePreviews((prev) => prev.filter((_, i) => i !== index));
  };

  const onSubmit = async (data: TourFormData) => {
    setIsLoading(true);
    setError(null);

    try {
      // Step 1: Create or update the tour
      const tourPayload = {
        ...data,
        included: includedItems,
        tags,
      };

      const tourResponse = await fetch(
        mode === "edit" && initialData?.id
          ? `/api/tours/${initialData.id}`
          : "/api/tours",
        {
          method: mode === "edit" ? "PATCH" : "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(tourPayload),
        }
      );

      if (!tourResponse.ok) {
        const errorData = await tourResponse.json();
        throw new Error(errorData.error || "Failed to save tour");
      }

      const { tour } = await tourResponse.json();

      // Show success toast for tour creation/update
      toast.success(
        mode === "edit" ? "Tour updated successfully!" : "Tour created successfully!",
        {
          description: mode === "edit" 
            ? "Your tour has been updated." 
            : "Your tour has been created.",
        }
      );

      // Step 2: Upload images if any
      if (images.length > 0) {
        setUploadingImages(true);
        const formData = new FormData();
        images.forEach((image) => {
          formData.append("images", image);
        });

        const imageResponse = await fetch(`/api/tours/${tour.id}/images`, {
          method: "POST",
          body: formData,
        });

        if (!imageResponse.ok) {
          toast.error("Failed to upload some images", {
            description: "Your tour was saved, but some images couldn't be uploaded.",
          });
        } else {
          toast.success("Images uploaded successfully!", {
            description: `${images.length} image${images.length > 1 ? 's' : ''} uploaded.`,
          });
        }
      }

      // Redirect to preview page
      router.push(`/tours/preview/${tour.id}`);
      router.refresh();
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : "Something went wrong";
      setError(errorMessage);
      toast.error("Failed to save tour", {
        description: errorMessage,
      });
    } finally {
      setIsLoading(false);
      setUploadingImages(false);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
      {error && (
        <Alert variant="destructive">
          <AlertCircle className="h-4 w-4" />
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {/* Basic Information */}
      <Card>
        <CardHeader>
          <CardTitle>Basic Information</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div>
            <Label htmlFor="title">Tour Title *</Label>
            <Input
              id="title"
              {...register("title")}
              placeholder="e.g., Zurich Old Town Walking Tour"
            />
            {errors.title && (
              <p className="text-sm text-destructive mt-1">
                {errors.title.message}
              </p>
            )}
          </div>

          <div>
            <Label htmlFor="description">Description *</Label>
            <Textarea
              id="description"
              {...register("description")}
              placeholder="Describe what makes your tour special..."
              rows={6}
            />
            {errors.description && (
              <p className="text-sm text-destructive mt-1">
                {errors.description.message}
              </p>
            )}
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <Label htmlFor="city">City *</Label>
              <Input id="city" {...register("city")} placeholder="Zurich" />
              {errors.city && (
                <p className="text-sm text-destructive mt-1">
                  {errors.city.message}
                </p>
              )}
            </div>

            <div>
              <Label htmlFor="meetingPoint">Meeting Point</Label>
              <Input
                id="meetingPoint"
                {...register("meetingPoint")}
                placeholder="e.g., Central Station, Main Hall"
              />
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Meeting Point & Location */}
      <Card>
        <CardHeader>
          <CardTitle>Meeting Point & Location</CardTitle>
        </CardHeader>
        <CardContent>
          <LocationPicker
            onLocationSelect={(lat, lng, address) => {
              setValue("meetingPointLat", lat);
              setValue("meetingPointLng", lng);
              setValue("meetingPoint", address);
            }}
            initialLat={initialData?.meetingPointLat}
            initialLng={initialData?.meetingPointLng}
            initialAddress={initialData?.meetingPoint}
          />
        </CardContent>
      </Card>

      {/* Tour Details */}
      <Card>
        <CardHeader>
          <CardTitle>Tour Details</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
              <Label htmlFor="durationMin">Duration (minutes) *</Label>
              <Input
                id="durationMin"
                type="number"
                {...register("durationMin", { valueAsNumber: true })}
                placeholder="180"
              />
              {errors.durationMin && (
                <p className="text-sm text-destructive mt-1">
                  {errors.durationMin.message}
                </p>
              )}
            </div>

            <div>
              <Label htmlFor="priceCents">
                Price (CHF) *
                {priceCents > 0 && (
                  <span className="ml-2 text-muted-foreground">
                    = CHF {(priceCents / 100).toFixed(2)}
                  </span>
                )}
              </Label>
              <Input
                id="priceCents"
                type="number"
                {...register("priceCents", { valueAsNumber: true })}
                placeholder="5000"
                step="100"
              />
              {errors.priceCents && (
                <p className="text-sm text-destructive mt-1">
                  {errors.priceCents.message}
                </p>
              )}
              <p className="text-xs text-muted-foreground mt-1">
                Enter price in cents (e.g., 5000 = CHF 50.00)
              </p>
            </div>

            <div>
              <Label htmlFor="maxGuests">Max Guests *</Label>
              <Input
                id="maxGuests"
                type="number"
                {...register("maxGuests", { valueAsNumber: true })}
                placeholder="10"
              />
              {errors.maxGuests && (
                <p className="text-sm text-destructive mt-1">
                  {errors.maxGuests.message}
                </p>
              )}
            </div>
          </div>

          {/* Included Items */}
          <div>
            <Label>What&apos;s Included</Label>
            <div className="flex gap-2 mt-2">
              <Input
                value={includedInput}
                onChange={(e) => setIncludedInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    addIncludedItem();
                  }
                }}
                placeholder="e.g., Drinks and snacks"
              />
              <Button type="button" onClick={addIncludedItem} size="icon">
                <Plus className="h-4 w-4" />
              </Button>
            </div>
            <div className="flex flex-wrap gap-2 mt-2">
              {includedItems.map((item) => (
                <Badge key={item} variant="secondary">
                  {item}
                  <button
                    type="button"
                    onClick={() => removeIncludedItem(item)}
                    className="ml-2 hover:text-destructive"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </Badge>
              ))}
            </div>
          </div>

          {/* Tags */}
          <div>
            <Label>Tags</Label>
            <div className="flex gap-2 mt-2">
              <Input
                value={tagInput}
                onChange={(e) => setTagInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    addTag();
                  }
                }}
                placeholder="e.g., walking, food, history"
              />
              <Button type="button" onClick={addTag} size="icon">
                <Plus className="h-4 w-4" />
              </Button>
            </div>
            <div className="flex flex-wrap gap-2 mt-2">
              {tags.map((tag) => (
                <Badge key={tag}>
                  {tag}
                  <button
                    type="button"
                    onClick={() => removeTag(tag)}
                    className="ml-2 hover:text-destructive"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </Badge>
              ))}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Images */}
      <Card>
        <CardHeader>
          <CardTitle>Images</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div>
            <Label htmlFor="images">Upload Images (Max 10, 5MB each)</Label>
            <div className="mt-2">
              <label
                htmlFor="images"
                className="flex items-center justify-center w-full h-32 border-2 border-dashed rounded-lg cursor-pointer hover:bg-accent"
              >
                <div className="text-center">
                  <Upload className="mx-auto h-8 w-8 text-muted-foreground" />
                  <p className="mt-2 text-sm text-muted-foreground">
                    Click to upload images
                  </p>
                </div>
                <input
                  id="images"
                  type="file"
                  accept="image/*"
                  multiple
                  onChange={handleImageSelect}
                  className="hidden"
                />
              </label>
            </div>

            {imagePreviews.length > 0 && (
              <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-4">
                {imagePreviews.map((preview, index) => (
                  <div key={index} className="relative group">
                    <Image
                      src={preview}
                      alt={`Preview ${index + 1}`}
                      width={200}
                      height={200}
                      className="rounded-lg object-cover w-full h-32"
                    />
                    <button
                      type="button"
                      onClick={() => removeImage(index)}
                      className="absolute top-2 right-2 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity"
                    >
                      <X className="h-4 w-4" />
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        </CardContent>
      </Card>

      {/* Publishing */}
      <Card>
        <CardHeader>
          <CardTitle>Publishing</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center justify-between">
            <div>
              <Label htmlFor="published">Publish Tour</Label>
              <p className="text-sm text-muted-foreground">
                Make this tour visible to the public
              </p>
            </div>
            <Switch 
              id="published" 
              checked={published}
              onCheckedChange={(checked) => setValue("published", checked)}
            />
          </div>
        </CardContent>
      </Card>

      {/* Submit */}
      <div className="flex gap-4">
        <Button
          type="submit"
          disabled={isLoading || uploadingImages}
          className="flex-1"
        >
          {isLoading || uploadingImages ? (
            <>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              {uploadingImages ? "Uploading images..." : "Saving..."}
            </>
          ) : mode === "edit" ? (
            "Update Tour"
          ) : (
            "Create Tour"
          )}
        </Button>
        <Button
          type="button"
          variant="outline"
          onClick={() => router.back()}
          disabled={isLoading}
        >
          Cancel
        </Button>
      </div>
    </form>
  );
}
