import { useState, useEffect, useCallback, useMemo } from 'react';
import { apiFetch } from '@/utils/api';
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
import { useDebounce } from '@/hooks/useDebounce';
import { Search } from "lucide-react";
import { ScrollArea } from "@/components/ui/scroll-area";
import { toast } from "sonner";
import config from "@/config";

interface VendorSetting {
  vendor: string;
  default_lead_time_days: number | null;
  default_days_of_stock: number | null;
  updated_at: string;
}

export function VendorSettings() {
  const [settings, setSettings] = useState<VendorSetting[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [pageSize] = useState(50);
  const [totalCount, setTotalCount] = useState(0);
  const [searchInputValue, setSearchInputValue] = useState('');
  const searchQuery = useDebounce(searchInputValue, 300); // 300ms debounce
  const [pendingChanges, setPendingChanges] = useState<Record<string, boolean>>({});

  // Use useCallback to avoid unnecessary re-renders
  const loadSettings = useCallback(async () => {
    try {
      setLoading(true);
      const response = await apiFetch(`${config.apiUrl}/config/vendors?page=${page}&pageSize=${pageSize}&search=${encodeURIComponent(searchQuery)}`, {
        credentials: 'include'
      });
      if (!response.ok) {
        throw new Error('Failed to load vendor settings');
      }
      const data = await response.json();
      setSettings(data.items);
      setTotalCount(data.total);
    } catch (error) {
      toast.error(`Failed to load settings: ${error instanceof Error ? error.message : 'Unknown error'}`);
    } finally {
      setLoading(false);
    }
  }, [page, searchQuery, pageSize]);

  useEffect(() => {
    loadSettings();
  }, [loadSettings]);

  const updateSetting = useCallback((vendor: string, field: keyof VendorSetting, value: any) => {
    setSettings(prev => prev.map(setting => 
      setting.vendor === vendor ? { ...setting, [field]: value } : setting
    ));
    setPendingChanges(prev => ({ ...prev, [vendor]: true }));
  }, []);

  const handleSaveSetting = useCallback(async (vendor: string) => {
    try {
      const setting = settings.find(s => s.vendor === vendor);
      if (!setting) return;

      const response = await apiFetch(`${config.apiUrl}/config/vendors/${encodeURIComponent(vendor)}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({
          default_lead_time_days: setting.default_lead_time_days,
          default_days_of_stock: setting.default_days_of_stock
        })
      });

      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to update vendor setting');
      }

      toast.success(`Settings updated for vendor ${vendor}`);
      setPendingChanges(prev => ({ ...prev, [vendor]: false }));
    } catch (error) {
      toast.error(`Failed to update setting: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }, [settings]);

  const handleResetToDefault = useCallback(async (vendor: string) => {
    try {
      const response = await apiFetch(`${config.apiUrl}/config/vendors/${encodeURIComponent(vendor)}/reset`, {
        method: 'POST',
        credentials: 'include'
      });

      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to reset vendor setting');
      }

      toast.success(`Settings reset for vendor ${vendor}`);
      loadSettings(); // Reload settings to get defaults
    } catch (error) {
      toast.error(`Failed to reset setting: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }, [loadSettings]);

  const totalPages = useMemo(() => Math.ceil(totalCount / pageSize), [totalCount, pageSize]);
  
  // Generate page numbers for pagination
  const paginationItems = useMemo(() => {
    const pages = [];
    const maxVisiblePages = 5;
    
    // Always include first page
    pages.push(1);
    
    // Calculate range of visible pages
    let startPage = Math.max(2, page - Math.floor(maxVisiblePages / 2));
    let endPage = Math.min(totalPages - 1, startPage + maxVisiblePages - 3);
    
    // Adjust if we're near the end
    if (endPage <= startPage) {
      endPage = Math.min(totalPages - 1, startPage + 1);
    }
    
    // Add ellipsis after first page if needed
    if (startPage > 2) {
      pages.push('ellipsis1');
    }
    
    // Add visible pages
    for (let i = startPage; i <= endPage; i++) {
      pages.push(i);
    }
    
    // Add ellipsis before last page if needed
    if (endPage < totalPages - 1) {
      pages.push('ellipsis2');
    }
    
    // Always include last page if it exists and is not already included
    if (totalPages > 1) {
      pages.push(totalPages);
    }
    
    return pages;
  }, [page, totalPages]);
  
  if (loading && settings.length === 0) {
    return <div className="py-4">Loading settings...</div>;
  }

  return (
    <div className="max-w-[900px] space-y-6">
      <Card>
        <CardHeader>
          <CardTitle>Vendor-Specific Settings</CardTitle>
          <CardDescription>Configure default settings for products from specific vendors</CardDescription>
          
          <div className="relative">
            <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
            <Input
              type="search"
              placeholder="Search vendors..."
              className="pl-8"
              value={searchInputValue}
              onChange={(e) => setSearchInputValue(e.target.value)}
            />
          </div>
        </CardHeader>
        <CardContent>
          <ScrollArea className="h-[500px] rounded-md border">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Vendor</TableHead>
                  <TableHead>Default Lead Time (days)</TableHead>
                  <TableHead>Default Days of Stock</TableHead>
                  <TableHead>Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {settings.map(setting => (
                  <TableRow key={setting.vendor}>
                    <TableCell>{setting.vendor}</TableCell>
                    <TableCell>
                      <Input
                        type="number"
                        min="1"
                        className="w-20 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
                        value={setting.default_lead_time_days ?? ''}
                        onChange={(e) => updateSetting(setting.vendor, 'default_lead_time_days', e.target.value ? parseInt(e.target.value) : null)}
                      />
                    </TableCell>
                    <TableCell>
                      <Input
                        type="number"
                        min="1"
                        className="w-20 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
                        value={setting.default_days_of_stock ?? ''}
                        onChange={(e) => updateSetting(setting.vendor, 'default_days_of_stock', e.target.value ? parseInt(e.target.value) : null)}
                      />
                    </TableCell>
                    <TableCell>
                      <div className="flex space-x-2">
                        <Button 
                          variant="outline" 
                          size="sm"
                          onClick={() => handleSaveSetting(setting.vendor)}
                          disabled={!pendingChanges[setting.vendor]}
                        >
                          Save
                        </Button>
                        <Button 
                          variant="outline" 
                          size="sm"
                          onClick={() => handleResetToDefault(setting.vendor)}
                        >
                          Reset
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </ScrollArea>
          
          {/* shadcn/ui Pagination */}
          {totalPages > 1 && (
            <div className="mt-4">
              <Pagination>
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious 
                      onClick={() => setPage(p => Math.max(1, p - 1))}
                      className={page === 1 ? "pointer-events-none opacity-50" : "cursor-pointer"}
                    />
                  </PaginationItem>
                  
                  {paginationItems.map((item, i) => (
                    typeof item === 'number' ? (
                      <PaginationItem key={i}>
                        <PaginationLink
                          onClick={() => setPage(item)}
                          isActive={page === item}
                        >
                          {item}
                        </PaginationLink>
                      </PaginationItem>
                    ) : (
                      <PaginationItem key={i}>
                        <span className="px-4 py-2">...</span>
                      </PaginationItem>
                    )
                  ))}
                  
                  <PaginationItem>
                    <PaginationNext 
                      onClick={() => setPage(p => Math.min(totalPages, p + 1))}
                      className={page === totalPages ? "pointer-events-none opacity-50" : "cursor-pointer"}
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
} 
