import { useEffect, useMemo, useState } from "react";
import {
  App as AntdApp,
  Button,
  Form,
  Input,
  Layout,
  message,
  Modal,
  Progress,
  Space,
  Table,
  Tabs,
  Tag,
  Typography,
  Upload,
} from "antd";
import { api, clearToken, getToken, setToken } from "../api/client";

const { Header, Content } = Layout;
const { Text } = Typography;

const taskColor = {
  queued: "default",
  running: "processing",
  success: "success",
  failed: "error",
};

export function App() {
  const [token, setTokenState] = useState(getToken());
  const [pwd, setPwd] = useState("");
  const [currentPath, setCurrentPath] = useState(".");
  const [entries, setEntries] = useState([]);
  const [tasks, setTasks] = useState([]);
  const [loading, setLoading] = useState(false);
  const [downloadOpen, setDownloadOpen] = useState(false);
  const [extractOpen, setExtractOpen] = useState(false);
  const [apiMsg, contextHolder] = message.useMessage();

  async function loadFiles(path = currentPath) {
    setLoading(true);
    try {
      const data = await api(`/api/fs/list?path=${encodeURIComponent(path)}`);
      setEntries(data.entries || []);
      setCurrentPath(path);
    } catch (err) {
      apiMsg.error(String(err.message || err));
    } finally {
      setLoading(false);
    }
  }

  async function loadTasks() {
    try {
      const data = await api("/api/tasks?limit=100");
      setTasks(data.tasks || []);
    } catch (err) {
      if (String(err.message || "").includes("401")) {
        clearToken();
        setTokenState("");
      }
    }
  }

  useEffect(() => {
    if (!token) return;
    loadFiles(".");
    loadTasks();
    const timer = setInterval(loadTasks, 2000);
    return () => clearInterval(timer);
  }, [token]);

  const columns = useMemo(
    () => [
      {
        title: "Name",
        dataIndex: "name",
        render: (_, row) =>
          row.isDir ? (
            <a onClick={() => loadFiles(row.path)}>{row.name}</a>
          ) : (
            <span>{row.name}</span>
          ),
      },
      {
        title: "Type",
        dataIndex: "isDir",
        render: (v) => (v ? "Directory" : "File"),
      },
      {
        title: "Size",
        dataIndex: "size",
      },
      {
        title: "Action",
        render: (_, row) => (
          <Space>
            <Button
              danger
              size="small"
              onClick={async () => {
                await api("/api/fs/delete", {
                  method: "POST",
                  body: JSON.stringify({ path: row.path }),
                });
                apiMsg.success("Deleted");
                loadFiles(currentPath);
              }}
            >
              Delete
            </Button>
            {!row.isDir && (
              <Button
                size="small"
                onClick={() =>
                  window.open(
                    `/api/fs/download?path=${encodeURIComponent(row.path)}`,
                    "_blank"
                  )
                }
              >
                Download
              </Button>
            )}
          </Space>
        ),
      },
    ],
    [currentPath]
  );

  if (!token) {
    return (
      <AntdApp>
        {contextHolder}
        <div className="center-card">
          <h2>FastFileViewer Login</h2>
          <Space.Compact style={{ width: "100%" }}>
            <Input.Password
              placeholder="Admin password"
              value={pwd}
              onChange={(e) => setPwd(e.target.value)}
              onPressEnter={async () => {
                try {
                  const data = await api("/api/login", {
                    method: "POST",
                    body: JSON.stringify({ password: pwd }),
                  });
                  setToken(data.token);
                  setTokenState(data.token);
                  setPwd("");
                } catch (err) {
                  apiMsg.error("Login failed");
                }
              }}
            />
            <Button
              type="primary"
              onClick={async () => {
                try {
                  const data = await api("/api/login", {
                    method: "POST",
                    body: JSON.stringify({ password: pwd }),
                  });
                  setToken(data.token);
                  setTokenState(data.token);
                  setPwd("");
                } catch (err) {
                  apiMsg.error("Login failed");
                }
              }}
            >
              Login
            </Button>
          </Space.Compact>
        </div>
      </AntdApp>
    );
  }

  return (
    <AntdApp>
      {contextHolder}
      <Layout style={{ minHeight: "100vh" }}>
        <Header className="header">
          <Text strong style={{ color: "#fff" }}>
            FastFileViewer
          </Text>
          <Button
            onClick={() => {
              clearToken();
              setTokenState("");
            }}
          >
            Logout
          </Button>
        </Header>
        <Content className="content">
          <Tabs
            items={[
              {
                key: "files",
                label: "Files",
                children: (
                  <>
                    <Space style={{ marginBottom: 12 }}>
                      <Text>Current: {currentPath}</Text>
                      <Button onClick={() => loadFiles(".")}>Root</Button>
                      <Button onClick={() => loadFiles(currentPath)}>Refresh</Button>
                      <Button onClick={() => setDownloadOpen(true)}>
                        URL Download
                      </Button>
                      <Button onClick={() => setExtractOpen(true)}>Extract</Button>
                      <Upload
                        showUploadList={false}
                        customRequest={async ({ file, onSuccess, onError }) => {
                          try {
                            const form = new FormData();
                            form.append("dir", currentPath);
                            form.append("file", file);
                            await api("/api/fs/upload", {
                              method: "POST",
                              body: form,
                            });
                            onSuccess?.("ok");
                            loadFiles(currentPath);
                          } catch (err) {
                            onError?.(err);
                          }
                        }}
                      >
                        <Button>Upload</Button>
                      </Upload>
                    </Space>
                    <Table
                      rowKey={(row) => row.path}
                      columns={columns}
                      dataSource={entries}
                      loading={loading}
                      pagination={false}
                    />
                  </>
                ),
              },
              {
                key: "tasks",
                label: "Tasks",
                children: (
                  <Table
                    rowKey={(row) => row.id}
                    dataSource={tasks}
                    pagination={false}
                    columns={[
                      { title: "ID", dataIndex: "id" },
                      { title: "Type", dataIndex: "type" },
                      {
                        title: "Status",
                        dataIndex: "status",
                        render: (v) => <Tag color={taskColor[v]}>{v}</Tag>,
                      },
                      {
                        title: "Progress",
                        dataIndex: "progress",
                        render: (v) => <Progress percent={v} size="small" />,
                      },
                      { title: "Source", dataIndex: "source" },
                      { title: "Target", dataIndex: "targetPath" },
                      { title: "Error", dataIndex: "error" },
                    ]}
                  />
                ),
              },
            ]}
          />
        </Content>
      </Layout>

      <Modal
        open={downloadOpen}
        title="Create Download Task"
        onCancel={() => setDownloadOpen(false)}
        footer={null}
      >
        <Form
          layout="vertical"
          onFinish={async (values) => {
            await api("/api/tasks/download", {
              method: "POST",
              body: JSON.stringify(values),
            });
            setDownloadOpen(false);
            loadTasks();
          }}
        >
          <Form.Item
            label="URL"
            name="url"
            rules={[{ required: true, message: "Please input URL" }]}
          >
            <Input placeholder="https://example.com/file.zip" />
          </Form.Item>
          <Form.Item
            label="Target Path"
            name="targetPath"
            initialValue={`${currentPath}/download.bin`}
            rules={[{ required: true, message: "Please input target path" }]}
          >
            <Input />
          </Form.Item>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </Form>
      </Modal>

      <Modal
        open={extractOpen}
        title="Create Extract Task"
        onCancel={() => setExtractOpen(false)}
        footer={null}
      >
        <Form
          layout="vertical"
          onFinish={async (values) => {
            await api("/api/tasks/extract", {
              method: "POST",
              body: JSON.stringify(values),
            });
            setExtractOpen(false);
            loadTasks();
          }}
        >
          <Form.Item
            label="Archive Path"
            name="sourcePath"
            rules={[{ required: true, message: "Please input archive path" }]}
          >
            <Input placeholder="path/to/file.zip" />
          </Form.Item>
          <Form.Item
            label="Target Dir"
            name="targetPath"
            initialValue={currentPath}
            rules={[{ required: true, message: "Please input target dir" }]}
          >
            <Input />
          </Form.Item>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </Form>
      </Modal>
    </AntdApp>
  );
}
