import { createFileRoute } from "@tanstack/react-router";
import { AppManagerTemplate } from "@/template/app-manager-template";
import {
  useGetSoftwareList,
  useGetRoomList,
  useUploadSoftware,
  useDeleteFile,
  useAddRequiredFile,
  useDeleteRequiredFile,
  useInstallMsi,
  useDownloadFiles,
} from "@/hooks/queries";
import { toast } from "sonner";
import type { ColumnDef } from "@tanstack/react-table";
import type { AxiosProgressEvent } from "axios";
import type { Version } from "@/types/file";
import { Check, X } from "lucide-react";
import { useState } from "react";

export const Route = createFileRoute("/_auth/apps/")({
  head: () => ({ meta: [{ title: "Quản lý phần mềm" }] }),
  component: AppsComponent,
});

function AppsComponent() {
  const { data, isLoading } = useGetSoftwareList();
  const { data: roomData } = useGetRoomList();

  const versionList: Version[] = Array.isArray(data)
    ? data
    : data
      ? [data]
      : [];

  const [table, setTable] = useState<any>();

  const uploadMutation = useUploadSoftware();

  const installMutation = useInstallMsi();

  const downloadMutation = useDownloadFiles();

  const deleteMutation = useDeleteFile();

  const addRequiredFileMutation = useAddRequiredFile();

  const deleteRequiredFileMutation = useDeleteRequiredFile();

  // Cột bảng
  const columns: ColumnDef<Version>[] = [
    { accessorKey: "version", header: "Phiên bản" },
    { accessorKey: "fileName", header: "Tên file" },
    { accessorKey: "folderPath", header: "Đường dẫn" },
    {
      accessorKey: "updatedAt",
      header: () => <div className="whitespace-normal max-w-xs">Thời gian cập nhật</div>,
      cell: ({ getValue }) =>
        getValue()
          ? new Date(getValue() as string).toLocaleString("vi-VN")
          : "N/A",
    },
    {
      accessorKey: "requestUpdateAt",
      header: () => <div className="whitespace-normal max-w-xs">Thời gian yêu cầu cài đặt/tải xuống</div>,
      cell: ({ getValue }) =>
        getValue()
          ? new Date(getValue() as string).toLocaleString("vi-VN")
          : "N/A",
    },
    {
      id: "required",
      header: () => <div className="whitespace-normal max-w-xs">Đã thêm vào danh sách</div>,
      cell: ({ row }) => {
        const isRequired = row.original.isRequired;
        return isRequired ? (
          <div className="flex items-center gap-1">
            <Check className="h-4 w-4 text-green-600" />
            <span className="text-sm text-green-600">Có</span>
          </div>
        ) : (
          <div className="flex items-center gap-1">
            <X className="h-4 w-4 text-gray-400" />
            <span className="text-sm text-gray-400">Không</span>
          </div>
        );
      },
      enableSorting: false,
      enableHiding: false,
    },
    {
      id: "select",
      header: () => <div className="whitespace-normal max-w-xs">Chọn</div>,
      cell: ({ row }) => (
        <input
          type="checkbox"
          checked={row.getIsSelected?.() ?? false}
          onChange={row.getToggleSelectedHandler?.()}
          disabled={installMutation.isPending}
        />
      ),
      enableSorting: false,
      enableHiding: false,
    },
  ];

  // Upload file MSI
  const handleUpload = async (
    fd: FormData,
    config?: { onUploadProgress?: (e: AxiosProgressEvent) => void }
  ) => {
    try {
      await uploadMutation.mutateAsync({
        formData: fd,
        onUploadProgress: config?.onUploadProgress,
      });
      toast.success("Upload thành công!");
    } catch (error: any) {
      console.error("Upload error:", error);
      toast.error("Upload thất bại!");
    }
  };

  // Callback khi chọn phòng
  const handleInstall = async (roomNames: string[]) => {
    if (!table) {
      toast.error("Không thể lấy thông tin bảng!");
      return;
    }

    const selectedRows = table.getSelectedRowModel().rows;
    if (selectedRows.length === 0) {
      toast.error("Vui lòng chọn ít nhất một file để cài đặt!");
      return;
    }

    const MsiFileIds = selectedRows.map((row: any) => row.original.id);

    try {
      for (const roomName of roomNames) {
        await installMutation.mutateAsync({
          roomName,
          data: { MsiFileIds },
        });
      }
      toast.success("Đã gửi yêu cầu cài đặt phần mềm cho các phòng đã chọn!");
    } catch (e) {
      toast.error("Có lỗi xảy ra khi cài đặt!");
    }
  };

  const handleDonwload = async (roomNames: string[]) => {
    if (!table) {
      toast.error("Không thể lấy thông tin bảng!");
      return;
    }

    const selectedRows = table.getSelectedRowModel().rows;
    if (selectedRows.length === 0) {
      toast.error("Vui lòng chọn ít nhất một file để tải!");
      return;
    }

    const MsiFileIds = selectedRows.map((row: any) => row.original.id);

    try {
      for (const roomName of roomNames) {
        await downloadMutation.mutateAsync({
          roomName,
          data: { MsiFileIds },
        });
      }
      toast.success("Đã gửi yêu cầu tải file cho các phòng đã chọn!");
    } catch (e) {
      toast.error("Có lỗi xảy ra khi tải!");
    }
  };

  const handleDelete = async () => {
    if (!table) {
      toast.error("Không thể lấy thông tin bảng!");
      return;
    }

    const selectedRows = table.getSelectedRowModel().rows;
    if (selectedRows.length === 0) {
      toast.error("Vui lòng chọn ít nhất một file để xóa!");
      return;
    }

    try {
      for (const row of selectedRows) {
        const { id } = row.original;
        await deleteMutation.mutateAsync(id);
      }
      toast.success("Xóa phần mềm thành công!");
    } catch (e) {
      toast.error("Xóa phần mềm thất bại!");
    }
  };

  const handleDeleteFromRequiredList = async () => {
    if (!table) return;

    const selectedRows = table.getSelectedRowModel().rows;

    try {
      for (const row of selectedRows) {
        const { id } = row.original;
        await deleteRequiredFileMutation.mutateAsync(id);
      }
      toast.success("Xóa file khỏi danh sách thành công!");
      if (table) {
        table.setRowSelection({});
      }
    } catch (e) {
      console.error("Delete from required list error:", e);
      toast.error("Có lỗi xảy ra khi xóa!");
    }
  };

  const handleDeleteFromServer = async () => {
    if (!table) return;

    const selectedRows = table.getSelectedRowModel().rows;

    try {
      for (const row of selectedRows) {
        const { id } = row.original;
        await deleteMutation.mutateAsync(id);
      }
      toast.success("Xóa phần mềm từ server thành công!");
      if (table) {
        table.setRowSelection({});
      }
    } catch (e) {
      console.error("Delete error:", e);
      toast.error("Có lỗi xảy ra khi xóa!");
    }
  };

  const handleAddToRequired = async () => {
    if (!table) {
      toast.error("Không thể lấy thông tin bảng!");
      return;
    }

    const selectedRows = table.getSelectedRowModel().rows;
    if (selectedRows.length === 0) {
      toast.error("Vui lòng chọn ít nhất một file!");
      return;
    }

    try {
      for (const row of selectedRows) {
        const { fileName, version } = row.original;
        await addRequiredFileMutation.mutateAsync({
          fileName,
          version,
        });
      }
      toast.success("Thêm file vào danh sách thành công!");
      table.setRowSelection({});
    } catch (e) {
      console.error("Add required file error:", e);
      toast.error("Có lỗi xảy ra!");
    }
  };

  return (
    <>
      <AppManagerTemplate<Version>
        title="Quản lý phần mềm"
        uploadFormTitle="Tải lên || Cập nhật file phần mềm"
        description="Quản lý và gửi yêu cầu cài đặt phần mềm hoặc file cấu hình"
        data={versionList}
        isLoading={isLoading}
        columns={columns}
        onUpload={handleUpload}
        onUpdate={handleInstall}
        onDownload={handleDonwload}
        onDelete={handleDelete}
        onDeleteFromServer={handleDeleteFromServer}
        onDeleteFromRequired={handleDeleteFromRequiredList}
        onAddToRequired={handleAddToRequired}
        updateLoading={installMutation.isPending}
        downloadLoading={downloadMutation.isPending}
        deleteLoading={deleteMutation.isPending || deleteRequiredFileMutation.isPending}
        addToRequiredLoading={addRequiredFileMutation.isPending}
        onTableInit={setTable}
        rooms={roomData}
      />
    </>
  );
}
