<script setup lang="ts">
  import { ref, onMounted } from "vue";
  import PageLayout from "@/components/PageLayout.vue";
  import {
    Card,
    CardHeader,
    CardTitle,
    CardContent,
    CardFooter,
  } from "@/components/ui/card";
  import { Button } from "@/components/ui/button";
  import { Input } from "@/components/ui/input";
  import { Label } from "@/components/ui/label";
  import { useCategoriesStore } from "@/stores/categories";
  import { Plus, Save, Trash2, Edit, X, Loader2 } from "lucide-vue-next";

  // Initialize store
  const categoriesStore = useCategoriesStore();

  // Local state
  const categories = ref<any[]>([]);
  const newCategory = ref({ name: "", icon: "", color: "#3b82f6" });
  const isAddingNew = ref(false);
  const isEditing = ref<string | null>(null);
  const editedCategory = ref({ name: "", icon: "", color: "" });
  const isLoading = ref(true);
  const errorMessage = ref("");

  // Standard colors for categories
  const standardColors = [
    "#ef4444", // red
    "#f97316", // orange
    "#f59e0b", // amber
    "#eab308", // yellow
    "#84cc16", // lime
    "#10b981", // emerald
    "#06b6d4", // cyan
    "#3b82f6", // blue
    "#6366f1", // indigo
    "#8b5cf6", // violet
    "#a855f7", // purple
    "#d946ef", // fuchsia
    "#ec4899", // pink
    "#6b7280", // gray
    "#000000", // black
  ];
  
  // Custom color input
  const isUsingCustomColor = ref(false);
  const customColorInput = ref("");

  // Standard icons for categories (emoji)
  const standardIcons = [
    "🍔",
    "🚗",
    "🏠",
    "🎬",
    "💰",
    "📱",
    "👕",
    "💊",
    "📚",
    "✈️",
    "🎁",
    "🔧",
    "💻",
    "🏋️",
    "🎮",
  ];

  // Load categories on component mount
  onMounted(async () => {
    isLoading.value = true;
    errorMessage.value = "";
    
    try {
      // Force refresh categories from server to ensure we have the latest
      await categoriesStore.refreshCategories();
      categories.value = [...categoriesStore.categories];
      
      // Initialize new category defaults
      newCategory.value = { 
        name: "", 
        icon: standardIcons[0],
        color: standardColors[0]
      };
    } catch (error) {
      console.error("Error loading categories:", error);
      errorMessage.value = "Failed to load categories";
    } finally {
      isLoading.value = false;
    }
  });

  // Start adding a new category
  const startAddNew = () => {
    newCategory.value = { name: "", icon: "📦", color: "#3b82f6" };
    isAddingNew.value = true;
    isEditing.value = null;
  };

  // Cancel adding or editing
  const cancelAction = () => {
    isAddingNew.value = false;
    isEditing.value = null;
  };

  // Add a new category
  const addCategory = async () => {
    // Reset error first
    errorMessage.value = "";
    
    // Validate name
    if (!newCategory.value.name.trim()) {
      errorMessage.value = "Category name cannot be empty";
      return;
    }

    // Check if name already exists
    const nameExists = categories.value.some(
      c => c.name.toLowerCase() === newCategory.value.name.toLowerCase()
    );
    if (nameExists) {
      errorMessage.value = "A category with this name already exists";
      return;
    }

    try {
      await categoriesStore.addCategory({
        name: newCategory.value.name,
        icon: newCategory.value.icon,
        color: newCategory.value.color,
      });

      categories.value = [...categoriesStore.categories];
      isAddingNew.value = false;
      newCategory.value = { name: "", icon: "", color: "#3b82f6" };
      errorMessage.value = "";
    } catch (error) {
      console.error("Error adding category:", error);
      errorMessage.value = "Failed to add category";
    }
  };

  // Start editing a category
  const startEdit = (category: any) => {
    isEditing.value = category._id;
    editedCategory.value = {
      name: category.name,
      icon: category.icon || "",
      color: category.color || "#3b82f6",
    };
    isAddingNew.value = false;
  };

  // Update a category
  const updateCategory = async (categoryId: string) => {
    if (!editedCategory.value.name.trim()) {
      errorMessage.value = "Category name cannot be empty";
      return;
    }

    try {
      await categoriesStore.updateCategory({
        _id: categoryId,
        name: editedCategory.value.name,
        icon: editedCategory.value.icon,
        color: editedCategory.value.color,
      });

      categories.value = [...categoriesStore.categories];
      isEditing.value = null;
      errorMessage.value = "";
    } catch (error) {
      console.error("Error updating category:", error);
      errorMessage.value = "Failed to update category";
    }
  };

  // Delete a category
  const deleteCategory = async (categoryId: string) => {
    if (confirm("Are you sure you want to delete this category?")) {
      try {
        await categoriesStore.deleteCategory(categoryId);
        categories.value = [...categoriesStore.categories];
        isEditing.value = null;
        errorMessage.value = "";
      } catch (error) {
        console.error("Error deleting category:", error);
        errorMessage.value = "Failed to delete category";
      }
    }
  };
</script>

<template>
  <PageLayout header="Categories">
    <div class="max-w-4xl mx-auto">
      <Card>
        <CardHeader class="flex flex-row items-center justify-between">
          <div>
            <CardTitle class="text-xl">Manage Categories</CardTitle>
            <p class="text-sm text-gray-500 mt-1">
              Create and organize categories to track your expenses and income
            </p>
          </div>
          <Button
            variant="default"
            size="sm"
            @click="startAddNew"
            v-if="!isAddingNew"
            class="flex items-center shadow-sm hover:shadow transition-all">
            <Plus class="mr-1 h-4 w-4" />
            Add Category
          </Button>
        </CardHeader>

        <CardContent>
          <!-- Error message -->
          <div
            v-if="errorMessage"
            class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded mb-4 text-sm">
            {{ errorMessage }}
          </div>

          <!-- Loading state -->
          <div v-if="isLoading" class="text-center py-8">
            <Loader2 class="h-8 w-8 mx-auto animate-spin text-primary" />
            <p class="mt-2 text-gray-500">Loading categories...</p>
          </div>

          <!-- No categories message -->
          <div
            v-else-if="categories.length === 0 && !isAddingNew"
            class="text-center py-12 px-4 border border-dashed rounded-lg bg-gray-50">
            <div class="flex flex-col items-center max-w-md mx-auto">
              <div class="w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center mb-4">
                <Plus class="h-8 w-8 text-primary" />
              </div>
              <h3 class="text-lg font-medium text-gray-900">No Categories Yet</h3>
              <p class="text-gray-500 mt-2 text-center">
                Categories help you organize and track your transactions. Create your first category to get started.
              </p>
              <Button class="mt-6" size="lg" @click="startAddNew">
                <Plus class="mr-2 h-5 w-5" />
                Add Your First Category
              </Button>
            </div>
          </div>
          
          <!-- Quick add form (shown when there are existing categories but not currently adding) -->
          <div 
            v-if="!isAddingNew && categories.length > 0 && !isEditing" 
            class="border border-dashed rounded-lg p-4 mb-6 hover:border-primary/30 hover:bg-primary/5 transition-colors">
            <div class="flex items-center gap-3">
              <Input 
                v-model="newCategory.name"
                placeholder="Quick add a new category..."
                class="flex-grow"
                @keyup.enter="addCategory" />
              <Button 
                variant="outline"
                @click="startAddNew"
                title="Advanced options">
                <Edit class="h-4 w-4" />
              </Button>
              <Button 
                @click="addCategory"
                :disabled="!newCategory.name.trim()"
                title="Add category">
                <Plus class="h-4 w-4" />
              </Button>
            </div>
          </div>

          <!-- Category editor form - Add new -->
          <div v-if="isAddingNew" class="border rounded-lg p-6 mb-6 bg-gray-50 shadow-sm">
            <div class="flex items-center justify-between mb-4">
              <h3 class="text-lg font-medium">Add New Category</h3>
              <button @click="cancelAction" class="text-gray-500 hover:text-gray-700">
                <X class="h-5 w-5" />
              </button>
            </div>
            
            <div class="space-y-6">
              <!-- Preview -->
              <div class="bg-white rounded-lg p-4 border flex items-center justify-center">
                <div class="flex flex-col items-center">
                  <div
                    class="w-16 h-16 rounded-full flex items-center justify-center text-2xl mb-2 text-white"
                    :style="{ backgroundColor: newCategory.color || '#3b82f6' }">
                    {{ newCategory.icon || "📦" }}
                  </div>
                  <span class="text-lg font-medium">{{ newCategory.name || "New Category" }}</span>
                  <span class="text-xs text-gray-500 mt-1">Preview</span>
                </div>
              </div>
              
              <div>
                <Label for="new-name" class="text-sm font-medium">Category Name</Label>
                <Input
                  id="new-name"
                  v-model="newCategory.name"
                  placeholder="e.g., Groceries, Transportation, Entertainment"
                  class="mt-1" />
                <p class="text-xs text-gray-500 mt-1">Choose a descriptive name for your category</p>
              </div>

              <div>
                <Label class="text-sm font-medium">Icon</Label>
                <div class="mt-2 grid grid-cols-5 sm:grid-cols-8 gap-2">
                  <button
                    v-for="icon in standardIcons"
                    :key="icon"
                    @click="newCategory.icon = icon"
                    class="w-10 h-10 flex items-center justify-center rounded-md border text-lg transition-all hover:bg-gray-100"
                    :class="{
                      'bg-primary/10 ring-2 ring-primary border-primary':
                        newCategory.icon === icon,
                    }">
                    {{ icon }}
                  </button>
                </div>
                <p class="text-xs text-gray-500 mt-1">Select an icon that represents this category</p>
              </div>

              <div>
                <Label class="text-sm font-medium">Color</Label>
                <div class="mt-2 flex flex-wrap gap-3">
                  <button
                    v-for="color in standardColors"
                    :key="color"
                    @click="() => {
                      newCategory.color = color;
                      isUsingCustomColor = false;
                    }"
                    class="w-10 h-10 rounded-full border hover:ring-2 hover:ring-offset-2 transition-all"
                    :style="{ backgroundColor: color }"
                    :class="{
                      'ring-2 ring-offset-2 scale-110': newCategory.color === color && !isUsingCustomColor,
                    }"></button>
                    
                  <!-- Custom color option -->
                  <button
                    @click="isUsingCustomColor = true"
                    class="w-10 h-10 rounded-full border flex items-center justify-center hover:ring-2 hover:ring-offset-2 transition-all bg-white"
                    :class="{
                      'ring-2 ring-offset-2': isUsingCustomColor,
                    }">
                    <span class="text-xs font-medium">+</span>
                  </button>
                </div>
                
                <!-- Custom color input -->
                <div v-if="isUsingCustomColor" class="mt-2">
                  <div class="flex gap-2 items-center">
                    <Input 
                      v-model="customColorInput"
                      placeholder="#RRGGBB" 
                      class="w-32"
                      maxlength="7"
                      @input="() => {
                        if(/^#[0-9A-Fa-f]{6}$/.test(customColorInput)) {
                          newCategory.color = customColorInput;
                        }
                      }" />
                    <div 
                      class="w-8 h-8 rounded-full border"
                      :style="{ backgroundColor: /^#[0-9A-Fa-f]{6}$/.test(customColorInput) ? customColorInput : '#CCCCCC' }">
                    </div>
                    <button 
                      @click="() => {
                        if(/^#[0-9A-Fa-f]{6}$/.test(customColorInput)) {
                          newCategory.color = customColorInput;
                        } else {
                          customColorInput = newCategory.color;
                        }
                      }"
                      class="text-xs text-blue-600 hover:text-blue-800">
                      Apply
                    </button>
                  </div>
                  <p class="text-xs text-gray-500 mt-1">Enter a color in hex format (e.g., #FF5500)</p>
                </div>
                <p class="text-xs text-gray-500 mt-1">Choose a color to easily identify this category</p>
              </div>

              <div class="flex justify-end gap-3 pt-2">
                <Button variant="outline" @click="cancelAction">
                  Cancel
                </Button>
                <Button 
                  @click="addCategory" 
                  :disabled="!newCategory.name.trim()"
                  class="min-w-28">
                  <Save class="mr-2 h-4 w-4" />
                  Save Category
                </Button>
              </div>
            </div>
          </div>

          <!-- Categories list -->
          <div
            v-if="!isLoading && (categories.length > 0 || isAddingNew)"
            class="space-y-3">
            <h3 class="text-sm font-medium text-gray-500 mt-2 mb-1">Your Categories</h3>
            <div
              v-for="category in categories"
              :key="category._id"
              class="border rounded-lg p-4 transition-all hover:bg-gray-50 group">
              <!-- View mode -->
              <div
                v-if="isEditing !== category._id"
                class="flex items-center justify-between">
                <div class="flex items-center">
                  <div
                    class="w-10 h-10 rounded-full flex items-center justify-center mr-3 text-white text-lg shadow-sm"
                    :style="{ backgroundColor: category.color || '#3b82f6' }">
                    {{ category.icon || "📦" }}
                  </div>
                  <div>
                    <span class="font-medium text-gray-900">{{ category.name }}</span>
                    <p class="text-xs text-gray-500">{{ category._id?.startsWith('default-') ? 'Default' : 'Custom' }} category</p>
                  </div>
                </div>
                <div class="flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
                  <button
                    @click="startEdit(category)"
                    class="p-2 text-gray-500 hover:text-blue-500 hover:bg-blue-50 rounded-full transition-colors"
                    title="Edit category">
                    <Edit class="h-4 w-4" />
                  </button>
                  <button
                    @click="deleteCategory(category._id)"
                    class="p-2 text-gray-500 hover:text-red-500 hover:bg-red-50 rounded-full transition-colors"
                    title="Delete category">
                    <Trash2 class="h-4 w-4" />
                  </button>
                </div>
              </div>

              <!-- Edit mode -->
              <div v-else class="space-y-5 bg-gray-50 p-3 rounded-md -m-2">
                <div class="flex items-center justify-between mb-2">
                  <h4 class="font-medium">Edit Category</h4>
                  <button @click="cancelAction" class="text-gray-500 hover:text-gray-700">
                    <X class="h-4 w-4" />
                  </button>
                </div>

                <!-- Preview -->
                <div class="bg-white rounded-lg p-3 border flex items-center justify-center">
                  <div class="flex flex-col items-center">
                    <div
                      class="w-12 h-12 rounded-full flex items-center justify-center text-xl mb-1 text-white"
                      :style="{ backgroundColor: editedCategory.color || '#3b82f6' }">
                      {{ editedCategory.icon || "📦" }}
                    </div>
                    <span class="text-sm font-medium">{{ editedCategory.name || "Category Name" }}</span>
                  </div>
                </div>

                <div>
                  <Label :for="`edit-name-${category._id}`" class="text-sm font-medium">
                    Category Name
                  </Label>
                  <Input
                    :id="`edit-name-${category._id}`"
                    v-model="editedCategory.name"
                    class="mt-1" />
                </div>

                <div>
                  <Label class="text-sm font-medium">Icon</Label>
                  <div class="mt-1 grid grid-cols-5 sm:grid-cols-7 gap-1">
                    <button
                      v-for="icon in standardIcons"
                      :key="icon"
                      @click="editedCategory.icon = icon"
                      class="w-9 h-9 flex items-center justify-center rounded border text-lg hover:bg-gray-100 transition-all"
                      :class="{
                        'bg-primary/10 ring-1 ring-primary border-primary':
                          editedCategory.icon === icon,
                      }">
                      {{ icon }}
                    </button>
                  </div>
                </div>

                <div>
                  <Label class="text-sm font-medium">Color</Label>
                  <div class="mt-1 flex flex-wrap gap-2">
                    <button
                      v-for="color in standardColors"
                      :key="color"
                      @click="() => {
                        editedCategory.color = color;
                        isUsingCustomColor = false;
                      }"
                      class="w-9 h-9 rounded-full border hover:ring-1 hover:ring-offset-1 transition-all"
                      :style="{ backgroundColor: color }"
                      :class="{
                        'ring-2 ring-offset-1 scale-110': editedCategory.color === color && !isUsingCustomColor,
                      }">
                    </button>
                    
                    <!-- Custom color option -->
                    <button
                      @click="isUsingCustomColor = true"
                      class="w-9 h-9 rounded-full border flex items-center justify-center hover:ring-1 hover:ring-offset-1 transition-all bg-white"
                      :class="{
                        'ring-2 ring-offset-1': isUsingCustomColor,
                      }">
                      <span class="text-xs font-medium">+</span>
                    </button>
                  </div>
                  
                  <!-- Custom color input -->
                  <div v-if="isUsingCustomColor" class="mt-2">
                    <div class="flex gap-2 items-center">
                      <Input 
                        v-model="customColorInput"
                        placeholder="#RRGGBB" 
                        class="w-32"
                        maxlength="7"
                        @input="() => {
                          if(/^#[0-9A-Fa-f]{6}$/.test(customColorInput)) {
                            editedCategory.color = customColorInput;
                          }
                        }" />
                      <div 
                        class="w-6 h-6 rounded-full border"
                        :style="{ backgroundColor: /^#[0-9A-Fa-f]{6}$/.test(customColorInput) ? customColorInput : '#CCCCCC' }">
                      </div>
                      <button 
                        @click="() => {
                          if(/^#[0-9A-Fa-f]{6}$/.test(customColorInput)) {
                            editedCategory.color = customColorInput;
                          } else {
                            customColorInput = editedCategory.color;
                          }
                        }"
                        class="text-xs text-blue-600 hover:text-blue-800">
                        Apply
                      </button>
                    </div>
                  </div>
                </div>

                <div class="flex justify-end gap-2 pt-2">
                  <Button variant="outline" size="sm" @click="cancelAction">
                    Cancel
                  </Button>
                  <Button size="sm" @click="updateCategory(category._id)" :disabled="!editedCategory.name.trim()">
                    <Save class="mr-1 h-4 w-4" />
                    Save Changes
                  </Button>
                </div>
              </div>
            </div>
          </div>
        </CardContent>
      </Card>
    </div>
  </PageLayout>
</template>
