import { useState, useEffect, useCallback } from 'react';
import {
  Drawer,
  Timeline,
  Button,
  Spin,
  Space,
  Typography,
  Popconfirm,
  message,
  Empty,
  Tag,
  Divider,
  theme,
} from 'antd';
import {
  HistoryOutlined,
  UserOutlined,
  RollbackOutlined,
  FileTextOutlined,
  EyeOutlined,
  CloseOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { api } from '@/lib/api';

dayjs.extend(relativeTime);

const { Text } = Typography;

interface DocHistoryDrawerProps {
  open: boolean;
  onClose: () => void;
  documentPath: string | null;
  currentContent: string;
  onRestore: (content: string) => void;
}

interface HistoryCommit {
  sha: string;
  commit: {
    message: string;
    author: { name: string; email: string; date: string };
    committer: { name: string; email: string; date: string };
  };
}

export function DocHistoryDrawer({
  open,
  onClose,
  documentPath,
  currentContent,
  onRestore,
}: DocHistoryDrawerProps) {
  const { token: themeToken } = theme.useToken();
  const [loading, setLoading] = useState(false);
  const [commits, setCommits] = useState<HistoryCommit[]>([]);
  const [selectedSha, setSelectedSha] = useState<string | null>(null);
  const [revisionContent, setRevisionContent] = useState<string | null>(null);
  const [loadingRevision, setLoadingRevision] = useState(false);
  const [restoring, setRestoring] = useState(false);

  const fetchHistory = useCallback(async () => {
    if (!documentPath) return;
    setLoading(true);
    try {
      const { data } = await api.get<{ commits: HistoryCommit[] }>(
        `/docs/history/${documentPath}`,
      );
      setCommits(data.commits);
    } catch {
      message.error('Failed to load version history');
    } finally {
      setLoading(false);
    }
  }, [documentPath]);

  useEffect(() => {
    if (open && documentPath) {
      fetchHistory();
      setSelectedSha(null);
      setRevisionContent(null);
    }
  }, [open, documentPath, fetchHistory]);

  const handleSelectCommit = async (sha: string) => {
    if (!documentPath) return;
    if (selectedSha === sha) {
      // Toggle off
      setSelectedSha(null);
      setRevisionContent(null);
      return;
    }

    setSelectedSha(sha);
    setLoadingRevision(true);
    try {
      const { data } = await api.get<{ sha: string; path: string; content: string }>(
        `/docs/revision/${sha}/${documentPath}`,
      );
      setRevisionContent(data.content);
    } catch {
      message.error('Failed to load revision');
      setRevisionContent(null);
    } finally {
      setLoadingRevision(false);
    }
  };

  const handleRestore = async () => {
    if (!documentPath || !selectedSha) return;
    setRestoring(true);
    try {
      const { data } = await api.post<{ success: boolean; path: string }>(
        `/docs/restore/${selectedSha}/${documentPath}`,
      );
      if (data.success && revisionContent) {
        onRestore(revisionContent);
        message.success('File restored to selected version');
        setSelectedSha(null);
        setRevisionContent(null);
        fetchHistory();
      } else {
        message.error('Failed to restore revision');
      }
    } catch {
      message.error('Failed to restore revision');
    } finally {
      setRestoring(false);
    }
  };

  const fileName = documentPath?.split('/').pop() || 'Document';

  // Simple line-by-line diff display
  const renderDiffView = () => {
    if (loadingRevision) {
      return (
        <div style={{ textAlign: 'center', padding: 20 }}>
          <Spin />
        </div>
      );
    }
    if (revisionContent === null) return null;

    const currentLines = currentContent.split('\n');
    const historicalLines = revisionContent.split('\n');

    return (
      <div style={{ marginTop: 12 }}>
        <Space style={{ marginBottom: 8 }}>
          <Tag color="blue">Viewing revision {selectedSha?.substring(0, 7)}</Tag>
          <Popconfirm
            title="Restore this version?"
            description="The current file content will be replaced with this revision."
            onConfirm={handleRestore}
            okText="Restore"
            cancelText="Cancel"
          >
            <Button
              type="primary"
              size="small"
              icon={<RollbackOutlined />}
              loading={restoring}
            >
              Restore
            </Button>
          </Popconfirm>
          <Button
            size="small"
            icon={<CloseOutlined />}
            onClick={() => {
              setSelectedSha(null);
              setRevisionContent(null);
            }}
          >
            Close
          </Button>
        </Space>

        <div
          style={{
            display: 'grid',
            gridTemplateColumns: '1fr 1fr',
            gap: 8,
          }}
        >
          <div>
            <Text type="secondary" strong style={{ display: 'block', marginBottom: 4, fontSize: 12 }}>
              Historical ({selectedSha?.substring(0, 7)})
            </Text>
            <pre
              style={{
                background: themeToken.colorBgLayout,
                border: `1px solid ${themeToken.colorBorderSecondary}`,
                borderRadius: themeToken.borderRadius,
                padding: 8,
                fontSize: 11,
                lineHeight: 1.5,
                overflow: 'auto',
                maxHeight: 400,
                whiteSpace: 'pre-wrap',
                wordBreak: 'break-word',
                margin: 0,
              }}
            >
              {historicalLines.map((line, i) => {
                const isDiff = i < currentLines.length && line !== currentLines[i];
                const isAdded = i >= currentLines.length;
                return (
                  <div
                    key={i}
                    style={{
                      background: isDiff
                        ? 'rgba(82, 196, 26, 0.1)'
                        : isAdded
                          ? 'rgba(82, 196, 26, 0.15)'
                          : undefined,
                    }}
                  >
                    <Text type="secondary" style={{ fontSize: 10, userSelect: 'none', marginRight: 8, display: 'inline-block', width: 30, textAlign: 'right' }}>
                      {i + 1}
                    </Text>
                    {line}
                  </div>
                );
              })}
            </pre>
          </div>

          <div>
            <Text type="secondary" strong style={{ display: 'block', marginBottom: 4, fontSize: 12 }}>
              Current
            </Text>
            <pre
              style={{
                background: themeToken.colorBgLayout,
                border: `1px solid ${themeToken.colorBorderSecondary}`,
                borderRadius: themeToken.borderRadius,
                padding: 8,
                fontSize: 11,
                lineHeight: 1.5,
                overflow: 'auto',
                maxHeight: 400,
                whiteSpace: 'pre-wrap',
                wordBreak: 'break-word',
                margin: 0,
              }}
            >
              {currentLines.map((line, i) => {
                const isDiff = i < historicalLines.length && line !== historicalLines[i];
                const isAdded = i >= historicalLines.length;
                return (
                  <div
                    key={i}
                    style={{
                      background: isDiff
                        ? 'rgba(245, 34, 45, 0.1)'
                        : isAdded
                          ? 'rgba(245, 34, 45, 0.15)'
                          : undefined,
                    }}
                  >
                    <Text type="secondary" style={{ fontSize: 10, userSelect: 'none', marginRight: 8, display: 'inline-block', width: 30, textAlign: 'right' }}>
                      {i + 1}
                    </Text>
                    {line}
                  </div>
                );
              })}
            </pre>
          </div>
        </div>
      </div>
    );
  };

  return (
    <Drawer
      title={
        <Space>
          <HistoryOutlined />
          <span>Version History</span>
        </Space>
      }
      open={open}
      onClose={onClose}
      width={selectedSha ? 800 : 420}
      destroyOnClose
    >
      {loading ? (
        <div style={{ textAlign: 'center', padding: 40 }}>
          <Spin size="large" />
        </div>
      ) : !documentPath ? (
        <Empty description="No document selected" />
      ) : commits.length === 0 ? (
        <Empty
          image={<FileTextOutlined style={{ fontSize: 48, color: themeToken.colorTextDisabled }} />}
          description="No version history available"
        >
          <Text type="secondary">
            History is recorded when files are saved with Gitea integration enabled.
          </Text>
        </Empty>
      ) : (
        <Space direction="vertical" style={{ width: '100%' }} size="small">
          <div>
            <Text type="secondary">File: </Text>
            <Text strong>{fileName}</Text>
          </div>
          <Text type="secondary" style={{ fontSize: 12 }}>
            {commits.length} revision{commits.length !== 1 ? 's' : ''}
          </Text>

          <Divider style={{ margin: '8px 0' }} />

          <Timeline
            items={commits.map((commit) => ({
              color: selectedSha === commit.sha ? themeToken.colorPrimary : themeToken.colorTextSecondary,
              children: (
                <div
                  key={commit.sha}
                  style={{
                    cursor: 'pointer',
                    padding: '4px 8px',
                    borderRadius: themeToken.borderRadius,
                    background:
                      selectedSha === commit.sha
                        ? themeToken.colorPrimaryBg
                        : undefined,
                    transition: 'background 0.2s',
                  }}
                  onClick={() => handleSelectCommit(commit.sha)}
                >
                  <div style={{ marginBottom: 2 }}>
                    <Text strong style={{ fontSize: 13 }}>
                      {commit.commit.message}
                    </Text>
                  </div>
                  <Space size={8}>
                    <Text type="secondary" style={{ fontSize: 11 }}>
                      <UserOutlined style={{ marginRight: 4 }} />
                      {commit.commit.author.name}
                    </Text>
                    <Text type="secondary" style={{ fontSize: 11 }}>
                      {dayjs(commit.commit.author.date).fromNow()}
                    </Text>
                    <Tag style={{ fontSize: 10 }}>{commit.sha.substring(0, 7)}</Tag>
                  </Space>
                  {selectedSha !== commit.sha && (
                    <div style={{ marginTop: 4 }}>
                      <Button
                        type="link"
                        size="small"
                        icon={<EyeOutlined />}
                        onClick={(e) => {
                          e.stopPropagation();
                          handleSelectCommit(commit.sha);
                        }}
                      >
                        View
                      </Button>
                    </div>
                  )}
                </div>
              ),
            }))}
          />

          {renderDiffView()}
        </Space>
      )}
    </Drawer>
  );
}
