import * as React from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Loader, RefreshCw, AlertCircle, CheckCircle, Info } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { toast } from "sonner";
import { DataTableColumnJSON } from "./form-data-table-columns";
import { ExcelDownload } from "./sedp-excel-download";

interface SEDPCompareDialogProps {
  isOpen: boolean;
  onClose: () => void;
  tableData: any[];
  columnsJSON: DataTableColumnJSON[];
  projectCode: string;
  formCode: string;
  fetchTagDataFromSEDP: (projectCode: string, formCode: string) => Promise<any>;
}

interface ComparisonResult {
  tagNo: string;
  tagDesc: string;
  isMatching: boolean;
  attributes: {
    key: string;
    label: string;
    localValue: any;
    sedpValue: any;
    isMatching: boolean;
    uom?: string;
  }[];
}

// Component for formatting display value with UOM
const DisplayValue = ({ value, uom, isSedp = false }: { value: any; uom?: string; isSedp?: boolean }) => {
  if (value === "" || value === null || value === undefined) {
    return <span>(empty)</span>;
  }
  
  // SEDP 값은 UOM을 표시하지 않음 (이미 포함되어 있다고 가정)
  if (isSedp) {
    return <span>{value}</span>;
  }
  
  // 로컬 값은 UOM과 함께 표시
  return (
    <span>
      {value}
      {uom && <span className="text-xs text-muted-foreground ml-1">{uom}</span>}
    </span>
  );
};

// 범례 컴포넌트 추가
const ColorLegend = () => {
  return (
    <div className="flex items-center gap-4 text-sm p-2 bg-muted/20 rounded">
      <div className="flex items-center gap-1.5">
        <Info className="h-4 w-4 text-muted-foreground" />
        <span className="font-medium">범례:</span>
      </div>
      <div className="flex items-center gap-3">
        <div className="flex items-center gap-1.5">
          <div className="h-3 w-3 rounded-full bg-red-500"></div>
          <span className="line-through text-red-500">로컬 값</span>
        </div>
        <div className="flex items-center gap-1.5">
          <div className="h-3 w-3 rounded-full bg-green-500"></div>
          <span className="text-green-500">SEDP 값</span>
        </div>
      </div>
    </div>
  );
};

export function SEDPCompareDialog({
  isOpen,
  onClose,
  tableData,
  columnsJSON,
  projectCode,
  formCode,
  fetchTagDataFromSEDP,
}: SEDPCompareDialogProps) {
  const [isLoading, setIsLoading] = React.useState(false);
  const [comparisonResults, setComparisonResults] = React.useState<ComparisonResult[]>([]);
  const [activeTab, setActiveTab] = React.useState("all");
  const [isExporting, setIsExporting] = React.useState(false);
  
  // Stats for summary
  const totalTags = comparisonResults.length;
  const matchingTags = comparisonResults.filter(r => r.isMatching).length;
  const nonMatchingTags = totalTags - matchingTags;

  // Get column label map and UOM map for better display
  const { columnLabelMap, columnUomMap } = React.useMemo(() => {
    const labelMap: Record<string, string> = {};
    const uomMap: Record<string, string> = {};
    
    columnsJSON.forEach(col => {
      labelMap[col.key] = col.displayLabel || col.label;
      if (col.uom) {
        uomMap[col.key] = col.uom;
      }
    });
    
    return { columnLabelMap: labelMap, columnUomMap: uomMap };
  }, [columnsJSON]);

  const fetchAndCompareData = React.useCallback(async () => {
    if (!projectCode || !formCode) {
      toast.error("Project code or form code is missing");
      return;
    }

    try {
      setIsLoading(true);
      
      // Fetch data from SEDP API
      const sedpData = await fetchTagDataFromSEDP(projectCode, formCode);
      
      // Get the table name from the response
      const tableName = Object.keys(sedpData)[0];
      const sedpTagEntries = sedpData[tableName] || [];
      
      // Create a map of SEDP data by TAG_NO for quick lookup
      const sedpTagMap = new Map();
      sedpTagEntries.forEach((entry: any) => {
        const tagNo = entry.TAG_NO;
        const attributesMap = new Map();
        
        // Convert attributes array to map for easier access
        if (Array.isArray(entry.ATTRIBUTES)) {
          entry.ATTRIBUTES.forEach((attr: any) => {
            attributesMap.set(attr.ATT_ID, attr.VALUE);
          });
        }
        
        sedpTagMap.set(tagNo, {
          tagDesc: entry.TAG_DESC,
          attributes: attributesMap
        });
      });
      
      // Compare with local table data
      const results: ComparisonResult[] = tableData.map(localItem => {
        const tagNo = localItem.TAG_NO;
        const sedpItem = sedpTagMap.get(tagNo);
        
        // If tag not found in SEDP data
        if (!sedpItem) {
          return {
            tagNo,
            tagDesc: localItem.TAG_DESC || "",
            isMatching: false,
            attributes: columnsJSON
              .filter(col => col.key !== "TAG_NO" && col.key !== "TAG_DESC")
              .map(col => ({
                key: col.key,
                label: columnLabelMap[col.key] || col.key,
                localValue: localItem[col.key],
                sedpValue: null,
                isMatching: false,
                uom: columnUomMap[col.key]
              }))
          };
        }
        
        // Compare attributes
        const attributeComparisons = columnsJSON
          .filter(col => col.key !== "TAG_NO" && col.key !== "TAG_DESC")
          .map(col => {
            const localValue = localItem[col.key];
            const sedpValue = sedpItem.attributes.get(col.key);
            const uom = columnUomMap[col.key];
            
            // Compare values (with type handling)
            let isMatching = false;
 
              // 문자열 비교
              // Normalize empty values
              const normalizedLocal = localValue === undefined || localValue === null ? "" : String(localValue).trim();
              const normalizedSedp = sedpValue === undefined || sedpValue === null ? "" : String(sedpValue).trim();
              isMatching = normalizedLocal === normalizedSedp;

            
            return {
              key: col.key,
              label: columnLabelMap[col.key] || col.key,
              localValue,
              sedpValue,
              isMatching,
              uom
            };
          });
        
        // Item is matching if all attributes match
        const isItemMatching = attributeComparisons.every(attr => attr.isMatching);
        
        return {
          tagNo,
          tagDesc: localItem.TAG_DESC || "",
          isMatching: isItemMatching,
          attributes: attributeComparisons
        };
      });
      
      setComparisonResults(results);
      
      // Show summary in toast
      const matchCount = results.filter(r => r.isMatching).length;
      const nonMatchCount = results.length - matchCount;
      
      if (nonMatchCount > 0) {
        toast.warning(`Found ${nonMatchCount} tags with differences`);
      } else if (results.length > 0) {
        toast.success(`All ${results.length} tags match with SEDP data`);
      } else {
        toast.info("No tags to compare");
      }
      
    } catch (error) {
      console.error("SEDP comparison error:", error);
      toast.error(`Failed to compare with SEDP: ${error instanceof Error ? error.message : 'Unknown error'}`);
    } finally {
      setIsLoading(false);
    }
  }, [projectCode, formCode, tableData, columnsJSON, fetchTagDataFromSEDP, columnLabelMap, columnUomMap]);
  
  // Fetch data when dialog opens
  React.useEffect(() => {
    if (isOpen) {
      fetchAndCompareData();
    }
  }, [isOpen, fetchAndCompareData]);
  
  // Filter results based on active tab
  const filteredResults = React.useMemo(() => {
    switch (activeTab) {
      case "matching":
        return comparisonResults.filter(r => r.isMatching);
      case "differences":
        return comparisonResults.filter(r => !r.isMatching);
      case "all":
      default:
        return comparisonResults;
    }
  }, [comparisonResults, activeTab]);

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-5xl max-h-[90vh] overflow-hidden flex flex-col">
        <DialogHeader>
          <DialogTitle className="flex items-center justify-between">
            <span>SEDP 데이터 비교</span>
            <div className="flex items-center gap-2">
              <Badge variant={matchingTags === totalTags ? "default" : "destructive"}>
                {matchingTags} / {totalTags} 일치
              </Badge>
              <Button 
                variant="outline" 
                size="sm" 
                onClick={fetchAndCompareData} 
                disabled={isLoading}
              >
                {isLoading ? (
                  <Loader className="h-4 w-4 animate-spin" />
                ) : (
                  <RefreshCw className="h-4 w-4" />
                )}
                <span className="ml-2">새로고침</span>
              </Button>
            </div>
          </DialogTitle>
        </DialogHeader>
        
        {/* 범례 추가 */}
        <div className="mb-4">
          <ColorLegend />
        </div>
        
        <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col overflow-hidden">
          <TabsList>
            <TabsTrigger value="all">전체 태그 ({totalTags})</TabsTrigger>
            <TabsTrigger value="differences">차이 있음 ({nonMatchingTags})</TabsTrigger>
            <TabsTrigger value="matching">일치함 ({matchingTags})</TabsTrigger>
          </TabsList>
          
          <TabsContent value={activeTab} className="flex-1 overflow-auto">
            {isLoading ? (
              <div className="flex items-center justify-center h-full">
                <Loader className="h-8 w-8 animate-spin mr-2" />
                <span>데이터 비교 중...</span>
              </div>
            ) : filteredResults.length > 0 ? (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-[180px]">Tag Number</TableHead>
                    <TableHead className="w-[200px]">Tag Description</TableHead>
                    <TableHead className="w-[120px]">상태</TableHead>
                    <TableHead>차이점</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filteredResults.map((result) => {
                    // Find differences to display
                    const differences = result.attributes.filter(attr => !attr.isMatching);
                    
                    return (
                      <TableRow key={result.tagNo} className={!result.isMatching ? "bg-muted/30" : ""}>
                        <TableCell className="font-medium">{result.tagNo}</TableCell>
                        <TableCell>{result.tagDesc}</TableCell>
                        <TableCell>
                          {result.isMatching ? (
                            <Badge variant="default" className="flex items-center gap-1">
                              <CheckCircle className="h-3 w-3" />
                              <span>일치</span>
                            </Badge>
                          ) : (
                            <Badge variant="destructive" className="flex items-center gap-1">
                              <AlertCircle className="h-3 w-3" />
                              <span>차이 있음</span>
                            </Badge>
                          )}
                        </TableCell>
                        <TableCell>
                          {differences.length > 0 ? (
                            <div className="space-y-1">
                              {differences.map((diff) => (
                                <div key={diff.key} className="text-sm">
                                  <span className="font-medium">{diff.label}: </span>
                                  <span className="line-through text-red-500 mr-2">
                                    <DisplayValue value={diff.localValue} uom={diff.uom} isSedp={false} />
                                  </span>
                                  <span className="text-green-500">
                                    <DisplayValue value={diff.sedpValue} uom={diff.uom} isSedp={true} />
                                  </span>
                                </div>
                              ))}
                            </div>
                          ) : (
                            <span className="text-muted-foreground">모든 값이 일치합니다</span>
                          )}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            ) : (
              <div className="flex items-center justify-center h-full text-muted-foreground">
                현재 필터에 맞는 태그가 없습니다
              </div>
            )}
          </TabsContent>
        </Tabs>
        
        <DialogFooter className="flex justify-between items-center gap-4 pt-4 border-t">
          <ExcelDownload
            comparisonResults={comparisonResults}
            formCode={formCode}
            disabled={isLoading || nonMatchingTags === 0}
          />
          <Button onClick={onClose}>닫기</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}