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 { Input } from "@/components/ui/input";
import { Loader, RefreshCw, AlertCircle, CheckCircle, Info, EyeOff, ChevronDown, ChevronRight, Search } 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";
import { Switch } from "../ui/switch";
import { Card, CardContent } from "@/components/ui/card";
import { useTranslation } from "@/i18n/client"
import { useParams } from "next/navigation"
import { fetchTagDataFromSEDP } from "@/lib/forms/sedp-actions";

interface SEDPCompareDialogProps {
  isOpen: boolean;
  onClose: () => void;
  tableData: unknown[];
  columnsJSON: DataTableColumnJSON[];
  projectCode: string;
  formCode: string;
  projectType:string;
  packageCode:string;
}

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

// Component for formatting display value with UOM
const DisplayValue = ({ value, uom, isSedp = false }: { value: unknown; uom?: string; isSedp?: boolean }) => {
  if (value === "" || value === null || value === undefined) {
    return <span className="text-muted-foreground italic">(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>
  );
};


export function SEDPCompareDialog({
  isOpen,
  onClose,
  tableData,
  columnsJSON,
  projectCode,
  formCode,
  projectType,
  packageCode
}: SEDPCompareDialogProps) {

  const params = useParams() || {}
  const lng = params.lng ? String(params.lng) : "ko"
  const { t } = useTranslation(lng, "engineering")

  // 범례 컴포넌트
  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">{t("labels.legend")}:</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">{t("labels.localValue")}</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">{t("labels.sedpValue")}</span>
          </div>
        </div>
      </div>
    );
  };

  // 확장 가능한 차이점 표시 컴포넌트
  const DifferencesCard = ({
    attributes,
    columnLabelMap,
    showOnlyDifferences
  }: {
    attributes: ComparisonResult['attributes'];
    columnLabelMap: Record<string, string>;
    showOnlyDifferences: boolean;
  }) => {
    const attributesToShow = showOnlyDifferences
      ? attributes.filter(attr => !attr.isMatching)
      : attributes;

    if (attributesToShow.length === 0) {
      return (
        <div className="text-center text-muted-foreground py-4">
          {t("messages.allAttributesMatch")}
        </div>
      );
    }

    return (
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 p-4">
        {attributesToShow.map((attr) => (
          <Card key={attr.key} className={`${!attr.isMatching ? 'border-red-200' : 'border-green-200'}`}>
            <CardContent className="p-3">
              <div className="font-medium text-sm mb-2 truncate" title={attr.label}>
                {attr.label}
                {attr.uom && <span className="text-xs text-muted-foreground ml-1">({attr.uom})</span>}
              </div>
              {attr.isMatching ? (
                <div className="text-sm">
                  <DisplayValue value={attr.localValue} uom={attr.uom} />
                </div>
              ) : (
                <div className="space-y-2">
                  <div className="flex items-center gap-2 text-sm">
                    <span className="text-xs text-muted-foreground min-w-[35px]">로컬:</span>
                    <span className="line-through text-red-500 flex-1">
                      <DisplayValue value={attr.localValue} uom={attr.uom} isSedp={false} />
                    </span>
                  </div>
                  <div className="flex items-center gap-2 text-sm">
                    <span className="text-xs text-muted-foreground min-w-[35px]">SEDP:</span>
                    <span className="text-green-500 flex-1">
                      <DisplayValue value={attr.sedpValue} uom={attr.uom} isSedp={true} />
                    </span>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        ))}
      </div>
    );
  };


  const [isLoading, setIsLoading] = React.useState(false);
  const [comparisonResults, setComparisonResults] = React.useState<ComparisonResult[]>([]);
  const [activeTab, setActiveTab] = React.useState("all");
  const [isExporting, setIsExporting] = React.useState(false);
  const [missingTags, setMissingTags] = React.useState<{
    localOnly: { tagNo: string; tagDesc: string }[];
    sedpOnly: { tagNo: string; tagDesc: string }[];
  }>({ localOnly: [], sedpOnly: [] });
  const [showOnlyDifferences, setShowOnlyDifferences] = React.useState(true);
  const [searchTerm, setSearchTerm] = React.useState("");
  const [expandedRows, setExpandedRows] = React.useState<Set<string>>(new Set());

  // Stats for summary
  const totalTags = comparisonResults.length;
  const matchingTags = comparisonResults.filter(r => r.isMatching).length;
  const nonMatchingTags = totalTags - matchingTags;
  const totalMissingTags = missingTags.localOnly.length + missingTags.sedpOnly.length;

  // 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]);

  // Filter and search results
  const filteredResults = React.useMemo(() => {
    let results = comparisonResults;

    // Filter by tab
    switch (activeTab) {
      case "matching":
        results = results.filter(r => r.isMatching);
        break;
      case "differences":
        results = results.filter(r => !r.isMatching);
        break;
      case "all":
      default:
        break;
    }

    // Apply search filter
    if (searchTerm.trim()) {
      const search = searchTerm.toLowerCase();
      results = results.filter(r =>
        r.tagNo.toLowerCase().includes(search) ||
        r.tagDesc.toLowerCase().includes(search)
      );
    }

    return results;
  }, [comparisonResults, activeTab, searchTerm]);

  // Toggle row expansion
  const toggleRowExpansion = (tagNo: string) => {
    const newExpanded = new Set(expandedRows);
    if (newExpanded.has(tagNo)) {
      newExpanded.delete(tagNo);
    } else {
      newExpanded.add(tagNo);
    }
    setExpandedRows(newExpanded);
  };

  // Auto-expand rows with differences when switching to differences tab
  React.useEffect(() => {
    if (activeTab === "differences") {
      const newExpanded = new Set<string>();
      filteredResults.filter(r => !r.isMatching).forEach(r => {
        newExpanded.add(r.tagNo);
      });
      setExpandedRows(newExpanded);
    }
  }, [activeTab, filteredResults]);

  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();

      const packageCodeAttId = projectType === "ship" ? "CM3003" : "ME5074";


      const tagEntries = sedpTagEntries.filter(entry => {
        if (Array.isArray(entry.ATTRIBUTES)) {
          const packageCodeAttr = entry.ATTRIBUTES.find(attr => attr.ATT_ID === packageCodeAttId);
          if (packageCodeAttr && packageCodeAttr.VALUE === packageCode) {
            return true;
          }
        }
        return false;
      });


      tagEntries.forEach((entry: Record<string, unknown>) => {
        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: Record<string, unknown>) => {
            attributesMap.set(attr.ATT_ID, attr.VALUE);
          });
        }

        sedpTagMap.set(tagNo, {
          tagDesc: entry.TAG_DESC,
          attributes: attributesMap
        });
      });

      // Create sets for finding missing tags
      const localTagNos = new Set(tableData.map(item => item.TAG_NO));
      const sedpTagNos = new Set(sedpTagMap.keys());

      // Find missing tags
      const localOnlyTags = tableData
        .filter(item => !sedpTagMap.has(item.TAG_NO))
        .map(item => ({ tagNo: item.TAG_NO, tagDesc: item.TAG_DESC || "" }));

      const sedpOnlyTags = Array.from(sedpTagMap.entries())
        .filter(([tagNo]) => !localTagNos.has(tagNo))
        .map(([tagNo, data]) => ({ tagNo, tagDesc: data.tagDesc || "" }));

      setMissingTags({
        localOnly: localOnlyTags,
        sedpOnly: sedpOnlyTags
      });

      // Compare with local table data (only for tags that exist in both systems)
      const results: ComparisonResult[] = tableData
        .filter(localItem => sedpTagMap.has(localItem.TAG_NO))
        .map(localItem => {
          const tagNo = localItem.TAG_NO;
          const sedpItem = sedpTagMap.get(tagNo);

          // Compare attributes
          const attributeComparisons = columnsJSON
            .filter(col => col.key !== "TAG_NO" && col.key !== "TAG_DESC" && col.key !== "status"&& col.key !== "CLS_ID")
            .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;

              // Special case: Empty SEDP value and 0 local value
              if ((sedpValue === "" || sedpValue === null || sedpValue === undefined) &&
                (localValue === 0 || localValue === "0")) {
                isMatching = true;
              } else {
                // Standard string comparison for other cases
                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;
      const missingCount = localOnlyTags.length + sedpOnlyTags.length;

      if (missingCount > 0) {
        toast.error(`Found ${missingCount} missing tags between systems`);
      }

      if (nonMatchCount > 0) {
        toast.warning(`Found ${nonMatchCount} tags with differences`);
      } else if (results.length > 0 && missingCount === 0) {
        toast.success(`All ${results.length} tags match with SEDP data`);
      } else if (results.length === 0 && missingCount === 0) {
        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, columnLabelMap, columnUomMap]);

  // Fetch data when dialog opens
  React.useEffect(() => {
    if (isOpen) {
      fetchAndCompareData();
    }
  }, [isOpen, fetchAndCompareData]);

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-6xl max-h-[90vh] overflow-hidden flex flex-col">
        <DialogHeader>
          <DialogTitle className="mb-2">{t("dialogs.sedpDataComparison")}</DialogTitle>
          <div className="flex items-center justify-between gap-2 pr-8">
            <div className="flex items-center gap-4">
              <div className="flex items-center gap-2">
                <Switch
                  checked={showOnlyDifferences}
                  onCheckedChange={setShowOnlyDifferences}
                  id="show-differences"
                />
                <label htmlFor="show-differences" className="text-sm cursor-pointer">
                  {t("switches.showOnlyDifferences")}
                </label>
              </div>

              {/* 검색 입력 */}
              <div className="relative">
                <Search className="absolute left-2 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                <Input
                  placeholder={t("placeholders.searchTagOrDesc")}
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                  className="pl-8 w-64"
                />
              </div>
            </div>

            <div className="flex items-center gap-2">
              <Badge variant={matchingTags === totalTags && totalMissingTags === 0 ? "default" : "destructive"}>
                {matchingTags} / {totalTags} 일치 {totalMissingTags > 0 ? `(${totalMissingTags} 누락)` : ''}
              </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">{t("buttons.refresh")}</span>
              </Button>
            </div>
          </div>
        </DialogHeader>

        {/* 범례 */}
        <div className="mb-4">
          <ColorLegend />
        </div>

        <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col overflow-hidden">
          <TabsList>
            <TabsTrigger value="all">{t("tabs.allTags")} ({totalTags})</TabsTrigger>
            <TabsTrigger value="differences">{t("tabs.differences")} ({nonMatchingTags})</TabsTrigger>
            <TabsTrigger value="matching">{t("tabs.matching")} ({matchingTags})</TabsTrigger>
            <TabsTrigger value="missing" className={totalMissingTags > 0 ? "text-red-500" : ""}>
              {t("tabs.missingTags")} ({totalMissingTags})
            </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>{t("messages.dataComparing")}</span>
              </div>
            ) : activeTab === "missing" ? (
              // Missing tags tab content
              <div className="space-y-6">
                {missingTags.localOnly.length > 0 && (
                  <div>
                    <h3 className="text-sm font-medium mb-2">{t("sections.localOnlyTags")} ({missingTags.localOnly.length})</h3>
                    <Table>
                      <TableHeader className="sticky top-0 bg-background z-10">
                        <TableRow>
                          <TableHead className="w-[180px]">{t("labels.tagNo")}</TableHead>
                          <TableHead>{t("labels.description")}</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {missingTags.localOnly.map((tag) => (
                          <TableRow key={tag.tagNo} className="bg-yellow-50 dark:bg-yellow-950/20">
                            <TableCell className="font-medium">{tag.tagNo}</TableCell>
                            <TableCell>{tag.tagDesc}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  </div>
                )}

                {missingTags.sedpOnly.length > 0 && (
                  <div>
                    <h3 className="text-sm font-medium mb-2">{t("sections.sedpOnlyTags")} ({missingTags.sedpOnly.length})</h3>
                    <Table>
                      <TableHeader className="sticky top-0 bg-background z-10">
                        <TableRow>
                          <TableHead className="w-[180px]">{t("labels.tagNo")}</TableHead>
                          <TableHead>{t("labels.description")}</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {missingTags.sedpOnly.map((tag) => (
                          <TableRow key={tag.tagNo} className="bg-blue-50 dark:bg-blue-950/20">
                            <TableCell className="font-medium">{tag.tagNo}</TableCell>
                            <TableCell>{tag.tagDesc}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  </div>
                )}

                {totalMissingTags === 0 && (
                  <div className="flex items-center justify-center h-full text-muted-foreground">
                    {t("messages.allTagsExistInBothSystems")}
                  </div>
                )}
              </div>
            ) : filteredResults.length > 0 ? (
              // 개선된 확장 가능한 테이블 구조
              <div className="border rounded-md">
                <Table>
                  <TableHeader className="sticky top-0 bg-muted/50 z-10">
                    <TableRow>
                      <TableHead className="w-12"></TableHead>
                      <TableHead className="w-[180px]">{t("labels.tagNo")}</TableHead>
                      <TableHead className="w-[250px]">{t("labels.description")}</TableHead>
                      <TableHead className="w-[120px]">{t("labels.status")}</TableHead>
                      <TableHead>차이점 개수</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {filteredResults.map((result) => (
                      <React.Fragment key={result.tagNo}>
                        {/* 메인 행 */}
                        <TableRow
                          className={`hover:bg-muted/20 cursor-pointer ${!result.isMatching ? "bg-muted/10" : ""}`}
                          onClick={() => toggleRowExpansion(result.tagNo)}
                        >
                          <TableCell>
                            {result.attributes.some(attr => !attr.isMatching) ? (
                              expandedRows.has(result.tagNo) ? (
                                <ChevronDown className="h-4 w-4" />
                              ) : (
                                <ChevronRight className="h-4 w-4" />
                              )
                            ) : null}
                          </TableCell>
                          <TableCell className="font-medium">
                            {result.tagNo}
                          </TableCell>
                          <TableCell title={result.tagDesc}>
                            <div className="truncate">
                              {result.tagDesc}
                            </div>
                          </TableCell>
                          <TableCell>
                            {result.isMatching ? (
                              <Badge variant="default" className="flex items-center gap-1">
                                <CheckCircle className="h-3 w-3" />
                                <span>{t("labels.matching")}</span>
                              </Badge>
                            ) : (
                              <Badge variant="destructive" className="flex items-center gap-1">
                                <AlertCircle className="h-3 w-3" />
                                <span>{t("labels.different")}</span>
                              </Badge>
                            )}
                          </TableCell>
                          <TableCell>
                            {!result.isMatching && (
                              <span className="text-sm text-muted-foreground">
                                {result.attributes.filter(attr => !attr.isMatching).length}{t("sections.differenceCount")}
                              </span>
                            )}
                          </TableCell>
                        </TableRow>

                        {/* 확장된 차이점 표시 행 */}
                        {expandedRows.has(result.tagNo) && (
                          <TableRow>
                            <TableCell colSpan={5} className="p-0 bg-muted/5">
                              <DifferencesCard
                                attributes={result.attributes}
                                columnLabelMap={columnLabelMap}
                                showOnlyDifferences={showOnlyDifferences}
                              />
                            </TableCell>
                          </TableRow>
                        )}
                      </React.Fragment>
                    ))}
                  </TableBody>
                </Table>
              </div>
            ) : (
              <div className="flex items-center justify-center h-full text-muted-foreground">
                {searchTerm ? t("messages.noSearchResults") : t("messages.noMatchingTags")}
              </div>
            )}
          </TabsContent>
        </Tabs>

        <DialogFooter className="flex justify-between items-center gap-4 pt-4 border-t">
          <ExcelDownload
            comparisonResults={comparisonResults}
            missingTags={missingTags}
            formCode={formCode}
            disabled={isLoading || (nonMatchingTags === 0 && totalMissingTags === 0)}
          />
          <Button onClick={onClose}>{t("buttons.close")}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}