import React, { useState, useEffect } from 'react';
import ReactQuill from 'react-quill-new';
import 'react-quill-new/dist/quill.snow.css';
import { useForm, Controller } from 'react-hook-form';
import { format } from 'date-fns';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/contexts/AuthContext';
import { useToast } from '@/hooks/use-toast';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Loader2, Send, AlertTriangle, DollarSign, FileText, Check, X, Tag, Settings2 } from 'lucide-react';
import { FileUploadDropzone } from '@/components/FileUploadDropzone';
import { cn } from '@/lib/utils';
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { OwnerUpdateTagManager } from './OwnerUpdateTagManager';
import { Combobox } from '@/components/Combobox';

export function OwnerUpdateForm({ units, selectedUnitId, associationId, onSuccess }) {
  const { user } = useAuth();
  const { toast } = useToast();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [violationsOpen, setViolationsOpen] = useState(false);
  const [collectionsOpen, setCollectionsOpen] = useState(false);
  const [tagsOpen, setTagsOpen] = useState(false);
  const [tagManagerOpen, setTagManagerOpen] = useState(false);
  const [availableTags, setAvailableTags] = useState([]);
  const [relatedData, setRelatedData] = useState({ violations: [], collections: [], loading: false });

  const { control, handleSubmit, reset, setValue, watch, formState: { errors } } = useForm({
    defaultValues: {
      unit_id: selectedUnitId || '',
      posted_at: format(new Date(), "yyyy-MM-dd'T'HH:mm"),
      content: '',
      attachments: [],
      collection_ids: [],
      violation_ids: [],
      tags: []
    }
  });

  const currentUnitId = watch('unit_id');
  const currentCollectionIds = watch('collection_ids');
  const currentViolationIds = watch('violation_ids');
  const currentTags = watch('tags') || [];

  useEffect(() => {
    if (selectedUnitId) setValue('unit_id', selectedUnitId);
  }, [selectedUnitId, setValue]);

  useEffect(() => {
    if (associationId) fetchTags(associationId);
  }, [associationId]);

  useEffect(() => {
    if (!currentUnitId) {
      setRelatedData({ violations: [], collections: [], loading: false });
      return;
    }
    const fetchRelated = async () => {
      setRelatedData(prev => ({ ...prev, loading: true }));
      try {
        const unit = units.find(u => u.id === currentUnitId);
        if (!unit) { setRelatedData({ violations: [], collections: [], loading: false }); return; }

        const [vRes, cRes] = await Promise.all([
          supabase.from('violations').select('id, violation_type, status, created_at, address').eq('association_id', unit.association_id).eq('unit_id', currentUnitId).order('created_at', { ascending: false }),
          supabase.from('collections').select('id, amount_owed, status, created_at, units(unit_number, address)').eq('association_id', unit.association_id).eq('unit_id', currentUnitId).order('created_at', { ascending: false })
        ]);
        setRelatedData({ violations: vRes.data || [], collections: cRes.data || [], loading: false });
      } catch (error) {
        setRelatedData(prev => ({ ...prev, loading: false }));
      }
    };
    fetchRelated();
  }, [currentUnitId, units]);

  const fetchTags = async (assocId) => {
    try {
      const { data } = await supabase.from('owner_update_tags').select('*').eq('association_id', assocId).order('name');
      setAvailableTags(data || []);
    } catch (error) {
      console.error('Error fetching tags:', error);
    }
  };

  const onSubmit = async (data) => {
    if (!user) return;
    setIsSubmitting(true);
    if (!data.unit_id) {
      toast({ variant: "destructive", title: "Validation Error", description: "Please select a unit." });
      setIsSubmitting(false);
      return;
    }
    const unit = units.find(u => u.id === data.unit_id);
    try {
      const { error } = await supabase.from('owner_updates').insert({
        unit_id: data.unit_id,
        association_id: unit?.association_id || associationId,
        title: 'Update',
        content: data.content,
        posted_at: new Date(data.posted_at).toISOString(),
        created_by: user.id,
        attachments: data.attachments || [],
        collection_ids: data.collection_ids || [],
        violation_ids: data.violation_ids || [],
        tags: data.tags || []
      });
      if (error) throw error;
      toast({ title: "Success", description: "Update posted successfully." });
      reset({ unit_id: data.unit_id, posted_at: format(new Date(), "yyyy-MM-dd'T'HH:mm"), content: '', attachments: [], collection_ids: [], violation_ids: [], tags: [] });
      if (onSuccess) onSuccess();
    } catch (err) {
      toast({ variant: "destructive", title: "Error", description: "Failed to post update." });
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleFilesUploaded = (files) => setValue('attachments', files);

  const toggleTag = (tag) => {
    const exists = currentTags.find(t => t.id === tag.id);
    setValue('tags', exists ? currentTags.filter(t => t.id !== tag.id) : [...currentTags, tag]);
  };

  const toggleViolation = (id) => {
    const current = currentViolationIds || [];
    setValue('violation_ids', current.includes(id) ? current.filter(i => i !== id) : [...current, id]);
  };

  const toggleCollection = (id) => {
    const current = currentCollectionIds || [];
    setValue('collection_ids', current.includes(id) ? current.filter(i => i !== id) : [...current, id]);
  };

  const getColorClass = (color) => {
    switch (color) {
      case 'red': return 'bg-red-100 text-red-700 hover:bg-red-200 border-red-200';
      case 'green': return 'bg-green-100 text-green-700 hover:bg-green-200 border-green-200';
      case 'amber': return 'bg-amber-100 text-amber-700 hover:bg-amber-200 border-amber-200';
      case 'purple': return 'bg-purple-100 text-purple-700 hover:bg-purple-200 border-purple-200';
      case 'slate': return 'bg-slate-100 text-slate-700 hover:bg-slate-200 border-slate-200';
      default: return 'bg-blue-100 text-blue-700 hover:bg-blue-200 border-blue-200';
    }
  };

  const modules = { toolbar: [[{ 'header': [1, 2, false] }], ['bold', 'italic', 'underline', 'strike', 'blockquote'], [{ 'list': 'ordered' }, { 'list': 'bullet' }], ['clean']] };

  const unitOptions = units.map(u => ({ value: u.id, label: `${u.unit_number || ''} - ${u.address || 'No address'}` }));

  return (
    <div className="space-y-6">
      <Card className="border shadow-sm">
        <CardHeader className="bg-muted/30 border-b py-4">
          <CardTitle className="text-sm font-medium flex items-center gap-2">
            <Send className="w-4 h-4 text-primary" /> Post New Update
          </CardTitle>
        </CardHeader>
        <CardContent className="p-4 space-y-4">
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
            <div className="space-y-2">
              <Label>Unit</Label>
              <Controller name="unit_id" control={control} rules={{ required: "Unit is required" }} render={({ field }) => (
                <Combobox options={unitOptions} value={field.value} onChange={(val) => { field.onChange(val); setValue('collection_ids', []); setValue('violation_ids', []); setValue('tags', []); }}
                  placeholder={units.length === 0 ? "No units available" : "Search units..."} disabled={units.length === 0}
                  className={cn(errors.unit_id ? "border-destructive" : "", "w-full")} emptyText="No units found." />
              )} />
              {errors.unit_id && <span className="text-xs text-destructive">{errors.unit_id.message}</span>}
            </div>

            <div className="space-y-2">
              <Label>Date & Time</Label>
              <Controller name="posted_at" control={control} rules={{ required: "Date is required" }} render={({ field }) => (
                <Input type="datetime-local" {...field} className={errors.posted_at ? "border-destructive" : ""} />
              )} />
            </div>

            {currentUnitId && (
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4 pt-2">
                <div className="space-y-2">
                  <Label className="flex items-center gap-2 text-amber-600 font-medium"><AlertTriangle className="w-4 h-4" /> Link Violations</Label>
                  <Popover open={violationsOpen} onOpenChange={setViolationsOpen}>
                    <PopoverTrigger asChild>
                      <Button variant="outline" role="combobox" className="w-full justify-between bg-background" type="button">
                        {currentViolationIds.length > 0 ? `${currentViolationIds.length} selected` : "Select violations..."}
                        <AlertTriangle className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[300px] p-0" align="start">
                      <Command><CommandInput placeholder="Search..." /><CommandList><CommandEmpty>No violations found.</CommandEmpty>
                        <CommandGroup>{(relatedData.violations || []).map(v => {
                          const isSelected = currentViolationIds.includes(v.id);
                          return (
                            <CommandItem key={v.id} value={v.violation_type + " " + (v.address || '') + " " + v.id} onSelect={() => toggleViolation(v.id)} className="cursor-pointer">
                              <div className={cn("mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground" : "opacity-50 [&_svg]:invisible")}><Check className="h-4 w-4" /></div>
                              <div className="flex flex-col flex-1 min-w-0">
                                <span className="font-medium truncate">{v.violation_type}</span>
                                {v.address && <span className="text-xs text-muted-foreground truncate">{v.address}</span>}
                                <span className="text-xs text-muted-foreground">{v.status} • {format(new Date(v.created_at), 'MMM d, yyyy')}</span>
                              </div>
                            </CommandItem>
                          );
                        })}</CommandGroup>
                      </CommandList></Command>
                    </PopoverContent>
                  </Popover>
                </div>

                <div className="space-y-2">
                  <Label className="flex items-center gap-2 text-green-600 font-medium"><DollarSign className="w-4 h-4" /> Link Collections</Label>
                  <Popover open={collectionsOpen} onOpenChange={setCollectionsOpen}>
                    <PopoverTrigger asChild>
                      <Button variant="outline" role="combobox" className="w-full justify-between bg-background" type="button">
                        {currentCollectionIds.length > 0 ? `${currentCollectionIds.length} selected` : "Select collections..."}
                        <DollarSign className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[300px] p-0" align="start">
                      <Command><CommandInput placeholder="Search..." /><CommandList><CommandEmpty>No collections found.</CommandEmpty>
                        <CommandGroup>{(relatedData.collections || []).map(c => {
                          const isSelected = currentCollectionIds.includes(c.id);
                          return (
                            <CommandItem key={c.id} value={(c.units?.address || '') + " " + c.amount_owed + " " + c.id} onSelect={() => toggleCollection(c.id)} className="cursor-pointer">
                              <div className={cn("mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground" : "opacity-50 [&_svg]:invisible")}><Check className="h-4 w-4" /></div>
                              <div className="flex flex-col flex-1 min-w-0">
                                <span className="font-medium truncate">{c.units?.address || c.units?.unit_number || 'Collection'}</span>
                                <span className="text-xs text-muted-foreground">${Number(c.amount_owed).toFixed(2)} • {c.status}</span>
                              </div>
                            </CommandItem>
                          );
                        })}</CommandGroup>
                      </CommandList></Command>
                    </PopoverContent>
                  </Popover>
                </div>
              </div>
            )}

            {currentUnitId && (
              <div className="space-y-2">
                <div className="flex justify-between items-center">
                  <Label className="flex items-center gap-2"><Tag className="w-4 h-4" /> Tags</Label>
                  <Button type="button" variant="ghost" size="sm" className="h-6 text-xs text-primary" onClick={() => setTagManagerOpen(true)}>
                    <Settings2 className="w-3 h-3 mr-1" /> Manage Tags
                  </Button>
                </div>
                <Popover open={tagsOpen} onOpenChange={setTagsOpen}>
                  <PopoverTrigger asChild>
                    <div className="min-h-[40px] p-2 border rounded-md bg-background cursor-pointer flex flex-wrap gap-2 hover:border-primary/50 transition-colors">
                      {currentTags.length === 0 && <span className="text-sm text-muted-foreground">Select tags...</span>}
                      {(currentTags || []).map(tag => (
                        <Badge key={tag.id} variant="secondary" className={cn("cursor-pointer", getColorClass(tag.color))}>
                          {tag.name}
                          <X className="w-3 h-3 ml-1 hover:text-destructive" onClick={(e) => { e.stopPropagation(); toggleTag(tag); }} />
                        </Badge>
                      ))}
                    </div>
                  </PopoverTrigger>
                  <PopoverContent className="w-[300px] p-0" align="start">
                    <Command><CommandInput placeholder="Search tags..." /><CommandList><CommandEmpty>No tags found.</CommandEmpty>
                      <CommandGroup>{(availableTags || []).map(tag => {
                        const isSelected = currentTags.some(t => t.id === tag.id);
                        return (
                          <CommandItem key={tag.id} value={tag.name} onSelect={() => toggleTag(tag)} className="cursor-pointer">
                            <div className={cn("mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground" : "opacity-50 [&_svg]:invisible")}><Check className="h-4 w-4" /></div>
                            <Badge variant="outline" className={getColorClass(tag.color)}>{tag.name}</Badge>
                          </CommandItem>
                        );
                      })}</CommandGroup>
                    </CommandList></Command>
                  </PopoverContent>
                </Popover>
              </div>
            )}

            <div className="space-y-2">
              <Label>Update Content</Label>
              <Controller name="content" control={control} rules={{ required: "Content cannot be empty" }} render={({ field }) => (
                <div className="h-64 mb-12"><ReactQuill theme="snow" value={field.value} onChange={field.onChange} modules={modules} className="bg-background h-52" /></div>
              )} />
              {errors.content && <span className="text-xs text-destructive">{errors.content.message}</span>}
            </div>

            <div className="space-y-2 pt-2">
              <Label className="flex items-center gap-2"><FileText className="w-4 h-4" /> Attachments</Label>
              <FileUploadDropzone bucketName="owner-update-attachments" onFilesUploaded={handleFilesUploaded} maxFiles={5} />
            </div>

            <Button type="submit" className="w-full" disabled={isSubmitting}>
              {isSubmitting ? <Loader2 className="w-4 h-4 animate-spin mr-2" /> : <Send className="w-4 h-4 mr-2" />}
              Post Update
            </Button>
          </form>
        </CardContent>

        <OwnerUpdateTagManager open={tagManagerOpen} onOpenChange={(open) => { setTagManagerOpen(open); if (!open && associationId) fetchTags(associationId); }} associationId={associationId} />
      </Card>
    </div>
  );
}
