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 { toast } from "sonner";
import config from '../../config';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Search } from 'lucide-react';
import { Switch } from "@/components/ui/switch";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";

interface ProductSetting {
  pid: string;
  lead_time_days: number | null;
  days_of_stock: number | null;
  safety_stock: number;
  forecast_method: string | null;
  exclude_from_forecast: boolean;
  updated_at: string;
  product_name?: string; // Added for display purposes
}

export function ProductSettings() {
  const [settings, setSettings] = useState<ProductSetting[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [pageSize] = useState(50);
  const [totalCount, setTotalCount] = useState(0);
  const [searchQuery, setSearchQuery] = useState('');
  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/products?page=${page}&pageSize=${pageSize}&search=${encodeURIComponent(searchQuery)}`, {
        credentials: 'include'
      });
      if (!response.ok) {
        throw new Error('Failed to load product 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((pid: string, field: keyof ProductSetting, value: any) => {
    setSettings(prev => prev.map(setting => 
      setting.pid === pid ? { ...setting, [field]: value } : setting
    ));
    setPendingChanges(prev => ({ ...prev, [pid]: true }));
  }, []);

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

      const response = await apiFetch(`${config.apiUrl}/config/products/${pid}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({
          lead_time_days: setting.lead_time_days,
          days_of_stock: setting.days_of_stock,
          safety_stock: setting.safety_stock,
          forecast_method: setting.forecast_method,
          exclude_from_forecast: setting.exclude_from_forecast
        })
      });

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

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

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

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

      toast.success(`Settings reset for product ${pid}`);
      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>Product-Specific Settings</CardTitle>
          <CardDescription>Configure settings for individual products that override global defaults</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 products by ID or name..."
              className="pl-8"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
          </div>
        </CardHeader>
        <CardContent>
          <ScrollArea className="h-[500px] rounded-md border">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Product ID</TableHead>
                  <TableHead>Lead Time (days)</TableHead>
                  <TableHead>Days of Stock</TableHead>
                  <TableHead>Safety Stock</TableHead>
                  <TableHead>Forecast Method</TableHead>
                  <TableHead>Exclude</TableHead>
                  <TableHead>Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {settings.map(setting => (
                  <TableRow key={setting.pid}>
                    <TableCell>{setting.pid} {setting.product_name && <span className="text-muted-foreground text-xs block">{setting.product_name}</span>}</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.lead_time_days ?? ''}
                        onChange={(e) => updateSetting(setting.pid, '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.days_of_stock ?? ''}
                        onChange={(e) => updateSetting(setting.pid, 'days_of_stock', e.target.value ? parseInt(e.target.value) : null)}
                      />
                    </TableCell>
                    <TableCell>
                      <Input
                        type="number"
                        min="0"
                        className="w-20 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
                        value={setting.safety_stock}
                        onChange={(e) => updateSetting(setting.pid, 'safety_stock', parseInt(e.target.value) || 0)}
                      />
                    </TableCell>
                    <TableCell>
                      <Select
                        value={setting.forecast_method || 'default'}
                        onValueChange={(value) => updateSetting(setting.pid, 'forecast_method', value === 'default' ? null : value)}
                      >
                        <SelectTrigger className="w-28">
                          <SelectValue placeholder="Default" />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="default">Default</SelectItem>
                          <SelectItem value="standard">Standard</SelectItem>
                          <SelectItem value="seasonal">Seasonal</SelectItem>
                        </SelectContent>
                      </Select>
                    </TableCell>
                    <TableCell>
                      <Switch
                        checked={setting.exclude_from_forecast}
                        onCheckedChange={(checked) => updateSetting(setting.pid, 'exclude_from_forecast', checked)}
                      />
                    </TableCell>
                    <TableCell>
                      <div className="flex space-x-2">
                        <Button 
                          variant="outline" 
                          size="sm"
                          onClick={() => handleSaveSetting(setting.pid)}
                          disabled={!pendingChanges[setting.pid]}
                        >
                          Save
                        </Button>
                        <Button 
                          variant="outline" 
                          size="sm"
                          onClick={() => handleResetToDefault(setting.pid)}
                        >
                          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}>
                        <PaginationEllipsis />
                      </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>
  );
} 
