import React, { useEffect, useRef, useState } from 'react';
import { useTheme } from '../../contexts/ThemeContext';
import { Content } from '../../components/layout/Content';
import { TPattern } from '../../components/common/TPattern';
import { getDocumentList, searchRegulations, uploadDocument, type RegulationSearchItem } from '../../api/docs';
import type { Doc } from '../../types';

type PipelineStatus = 'idle' | 'running' | 'completed' | 'error';

const PIPELINE_STEPS = [
  { name: 'LOAD' },
  { name: 'PARSE' },
  { name: 'CHUNK' },
  { name: 'EMBED' },
  { name: 'STORE' },
];

const STEP_DURATION_MS = 700;

function wait(ms: number) {
  return new Promise<void>((resolve) => {
    window.setTimeout(resolve, ms);
  });
}

export const DocsPage: React.FC = () => {
  const { theme, isDark } = useTheme();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const pipelineRunIdRef = useRef(0);

  const [activeStep, setActiveStep] = useState<number>(-1);
  const [completedSteps, setCompletedSteps] = useState<number[]>([]);
  const [pipelineStatus, setPipelineStatus] = useState<PipelineStatus>('idle');
  const [docs, setDocs] = useState<Doc[]>([]);
  const [uploading, setUploading] = useState(false);
  const [uploadFileName, setUploadFileName] = useState('');
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState('新能源汽车电池安全要求');
  const [searchResults, setSearchResults] = useState<RegulationSearchItem[]>([]);
  const [searchLoading, setSearchLoading] = useState(false);
  const [searchError, setSearchError] = useState('');

  useEffect(() => {
    void loadDocuments();
  }, []);

  useEffect(() => {
    void runSearch(searchQuery);
  }, []);

  useEffect(() => {
    return () => {
      pipelineRunIdRef.current += 1;
    };
  }, []);

  const resetPipeline = (status: PipelineStatus = 'idle') => {
    pipelineRunIdRef.current += 1;
    setActiveStep(-1);
    setCompletedSteps([]);
    setPipelineStatus(status);
  };

  const loadDocuments = async () => {
    setLoading(true);
    try {
      const response = await getDocumentList();
      const apiDocs: Doc[] = response.docs.map((doc) => ({
        id: parseInt(String(doc.id).replace('doc-', ''), 10) || Math.floor(Math.random() * 10000),
        name: doc.name,
        chunks: doc.chunks,
        size: doc.size_text || `${((doc.chunks * 8) / 1024).toFixed(1)}MB`,
        status: doc.status === 'indexed' ? 'indexed' : 'parsing',
        docId: doc.id,
        downloadUrl: doc.download_url,
      }));
      setDocs(apiDocs);
    } catch (error) {
      console.error('Failed to load documents:', error);
      setDocs([]);
    } finally {
      setLoading(false);
    }
  };

  const runPipelineFlow = async (runId: number, uploadPromise: Promise<Awaited<ReturnType<typeof uploadDocument>>>) => {
    const guardedSetActiveStep = (step: number) => {
      if (pipelineRunIdRef.current !== runId) return false;
      setActiveStep(step);
      return true;
    };

    const guardedCompleteStep = (step: number) => {
      if (pipelineRunIdRef.current !== runId) return false;
      setCompletedSteps((prev) => (prev.includes(step) ? prev : [...prev, step]));
      return true;
    };

    for (let index = 0; index < PIPELINE_STEPS.length - 1; index += 1) {
      if (!guardedSetActiveStep(index)) return;
      await wait(STEP_DURATION_MS);
      if (!guardedCompleteStep(index)) return;
    }

    if (!guardedSetActiveStep(PIPELINE_STEPS.length - 1)) return;
    await uploadPromise;
    if (!guardedCompleteStep(PIPELINE_STEPS.length - 1)) return;

    await wait(240);
    if (pipelineRunIdRef.current !== runId) return;

    setActiveStep(-1);
    setPipelineStatus('completed');
  };

  const handleFileSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file || uploading) return;

    const runId = pipelineRunIdRef.current + 1;
    pipelineRunIdRef.current = runId;

    setUploading(true);
    setUploadFileName(file.name);
    setActiveStep(-1);
    setCompletedSteps([]);
    setPipelineStatus('running');

    const fileSizeMB = (file.size / (1024 * 1024)).toFixed(1);
    const tempDocId = `pending-${Date.now()}`;
    const newDoc: Doc = {
      id: Date.now(),
      name: file.name,
      chunks: 0,
      size: `${fileSizeMB}MB`,
      status: 'parsing',
      docId: tempDocId,
    };

    setDocs((prev) => [newDoc, ...prev]);

    const uploadPromise = uploadDocument(file);
    void runPipelineFlow(runId, uploadPromise);

    try {
      const uploadRes = await uploadPromise;
      if (pipelineRunIdRef.current !== runId) return;

      setDocs((prev) =>
        prev.map((doc) =>
          doc.id === newDoc.id
            ? {
                ...doc,
                status: 'indexed',
                docId: uploadRes.doc_id,
                chunks: uploadRes.num_chunks || doc.chunks,
                summary: uploadRes.summary,
              }
            : doc
        )
      );

      setUploading(false);
      setUploadFileName('');
      void loadDocuments();
    } catch (error) {
      console.error('Upload failed:', error);
      if (pipelineRunIdRef.current !== runId) return;

      setUploading(false);
      setUploadFileName('');
      setDocs((prev) => prev.filter((doc) => doc.id !== newDoc.id));
      setPipelineStatus('error');
      setActiveStep(-1);
      setCompletedSteps([]);
    } finally {
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    }
  };

  const triggerFileUpload = () => {
    if (uploading) return;
    fileInputRef.current?.click();
  };

  const handleDragOver = (event: React.DragEvent) => {
    event.preventDefault();
    event.stopPropagation();
  };

  const handleDrop = (event: React.DragEvent) => {
    event.preventDefault();
    event.stopPropagation();

    const files = event.dataTransfer.files;
    if (files.length === 0 || uploading) return;

    const droppedFile = files[0];
    if (fileInputRef.current) {
      const dataTransfer = new DataTransfer();
      dataTransfer.items.add(droppedFile);
      fileInputRef.current.files = dataTransfer.files;
    }

    void handleFileSelect({
      target: { files: [droppedFile] as unknown as FileList },
    } as React.ChangeEvent<HTMLInputElement>);
  };

  const runSearch = async (query: string) => {
    if (!query.trim()) return;
    setSearchLoading(true);
    setSearchError('');
    try {
      const response = await searchRegulations(query.trim(), 8);
      setSearchResults(response.results);
    } catch (error) {
      console.error('Failed to search regulations:', error);
      setSearchError(error instanceof Error ? error.message : '检索失败');
      setSearchResults([]);
    } finally {
      setSearchLoading(false);
    }
  };

  const getStepStyle = (index: number) => {
    const isActive = activeStep === index;
    const isCompleted = completedSteps.includes(index);

    if (isActive) {
      return {
        background: theme.bgCard,
        border: `2px solid ${theme.accent}`,
        boxShadow: `0 0 12px ${theme.accent}40`,
      };
    }

    if (isCompleted) {
      return {
        background: theme.bgCard,
        border: `1px solid ${theme.green}`,
      };
    }

    return {
      background: theme.bgCard,
      border: `1px solid ${theme.border}`,
    };
  };

  const getCheckStyle = (index: number) => {
    const isActive = activeStep === index;
    const isCompleted = completedSteps.includes(index);

    if (isActive) {
      return {
        background: theme.gradientAccent,
        color: '#fff',
        animation: 'pulse 0.6s infinite',
      };
    }

    if (isCompleted) {
      return {
        background: theme.green,
        color: '#fff',
      };
    }

    return {
      background: theme.bgHover,
      color: theme.text3,
    };
  };

  const getPipelineHint = () => {
    if (pipelineStatus === 'running') {
      return activeStep >= 0 ? `${PIPELINE_STEPS[activeStep].name} · ${uploadFileName}` : `LOAD · ${uploadFileName}`;
    }
    if (pipelineStatus === 'completed') {
      return 'PIPELINE COMPLETE';
    }
    if (pipelineStatus === 'error') {
      return 'PIPELINE FAILED';
    }
    return 'WAITING FOR UPLOAD';
  };

  return (
    <Content>
      <TPattern />

      <section style={{ marginBottom: 56 }}>
        <h2
          style={{
            fontSize: 14,
            fontWeight: 600,
            color: theme.accent,
            marginBottom: 20,
            letterSpacing: '1px',
          }}
        >
          UPLOAD
        </h2>

        <input
          ref={fileInputRef}
          type="file"
          accept=".pdf,.docx,.doc"
          onChange={handleFileSelect}
          style={{ display: 'none' }}
        />

        <div
          onClick={triggerFileUpload}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
          style={{
            border: `2px solid ${uploading ? theme.accent : theme.border}`,
            borderRadius: 16,
            padding: 64,
            textAlign: 'center',
            background: theme.bgCard,
            transition: 'all 0.3s ease',
            cursor: uploading ? 'wait' : 'pointer',
            boxShadow: !isDark ? '0 4px 16px rgba(226,0,116,0.08)' : 'none',
            opacity: uploading ? 0.78 : 1,
          }}
        >
          <div
            style={{
              width: 80,
              height: 80,
              borderRadius: 20,
              background: theme.bgHover,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              margin: '0 auto 20px',
            }}
          >
            {uploading ? (
              <div style={{ animation: 'spin 1s linear infinite' }}>
                <svg width="36" height="36" viewBox="0 0 24 24" fill="none">
                  <circle
                    cx="12"
                    cy="12"
                    r="10"
                    stroke={theme.accent}
                    strokeWidth="2"
                    strokeDasharray="60"
                    strokeDashoffset="20"
                  />
                </svg>
              </div>
            ) : (
              <svg width="36" height="36" viewBox="0 0 24 24" fill="none">
                <path d="M12 4L12 16M12 4L7 9M12 4L17 9" stroke={theme.accent} strokeWidth="2" strokeLinecap="round" />
                <path d="M4 18H20" stroke={theme.accent} strokeWidth="2" strokeLinecap="round" />
              </svg>
            )}
          </div>

          <div style={{ fontSize: 16, fontWeight: 500, marginBottom: 8 }}>
            {uploading ? '正在上传并启动处理链路...' : '拖拽文件或点击上传'}
          </div>
          <div className="mono" style={{ fontSize: 12, color: theme.text3 }}>
            {uploading ? uploadFileName : 'PDF · DOCX · DOC · MAX 100MB'}
          </div>
        </div>
      </section>

      <section style={{ marginBottom: 40 }}>
        <h2
          style={{
            fontSize: 14,
            fontWeight: 600,
            color: theme.accent,
            marginBottom: 20,
            letterSpacing: '1px',
          }}
        >
          PROCESSING PIPELINE
        </h2>

        <div
          className="mono"
          style={{
            fontSize: 11,
            color:
              pipelineStatus === 'error'
                ? '#d64545'
                : pipelineStatus === 'completed'
                  ? theme.green
                  : theme.text3,
            letterSpacing: '1px',
            marginBottom: 12,
          }}
        >
          {getPipelineHint()}
        </div>

        <div style={{ display: 'flex', gap: 16 }}>
          {PIPELINE_STEPS.map((step, index) => {
            const stepStyle = getStepStyle(index);
            const checkStyle = getCheckStyle(index);
            const arrowActive = activeStep > index || completedSteps.includes(index);
            const isCompleted = completedSteps.includes(index);
            const isActive = activeStep === index;

            return (
              <div
                key={step.name}
                style={{
                  flex: 1,
                  padding: 20,
                  textAlign: 'center',
                  borderRadius: 12,
                  position: 'relative',
                  boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
                  transition: 'all 0.3s ease',
                  ...stepStyle,
                }}
              >
                <div
                  style={{
                    width: 36,
                    height: 36,
                    borderRadius: 8,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    margin: '0 auto 12px',
                    fontSize: 16,
                    transition: 'all 0.3s ease',
                    ...checkStyle,
                  }}
                >
                  {isActive ? step.name : isCompleted ? '✓' : step.name}
                </div>

                <div className="mono" style={{ fontSize: 12, fontWeight: 600 }}>
                  {step.name}
                </div>
                <div className="mono" style={{ fontSize: 10, color: theme.text3, marginTop: 8 }}>
                  {isCompleted ? 'DONE' : isActive ? 'RUNNING' : 'PENDING'}
                </div>

                {index < PIPELINE_STEPS.length - 1 && (
                  <div
                    style={{
                      position: 'absolute',
                      right: -8,
                      top: '50%',
                      transform: 'translateY(-50%)',
                      color: arrowActive ? theme.green : theme.borderLight,
                      fontWeight: arrowActive ? 700 : 400,
                      opacity: arrowActive ? 1 : 0.45,
                      transition: 'all 0.3s ease',
                    }}
                  >
                    →
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </section>

      <section style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24, marginBottom: 56 }}>
        <div>
          <h2
            style={{
              fontSize: 14,
              fontWeight: 600,
              color: theme.accent,
              marginBottom: 20,
              letterSpacing: '1px',
            }}
          >
            文档管理清单 ({loading ? '...' : docs.length})
          </h2>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {docs.map((doc) => (
              <div
                key={doc.id}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  padding: 20,
                  background: theme.bgCard,
                  borderRadius: 12,
                  border: `1px solid ${doc.status === 'parsing' ? theme.accent : theme.border}`,
                  transition: 'all 0.2s ease',
                  boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
                }}
              >
                <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
                  <div
                    style={{
                      width: 44,
                      height: 44,
                      borderRadius: 10,
                      background: theme.bgHover,
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}
                  >
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                      <path
                        d="M14 2H6C5 2 4 3 4 4V20C4 21 5 22 6 22H18C19 22 20 21 20 20V8L14 2Z"
                        stroke={theme.accent}
                        strokeWidth="1.5"
                      />
                      <path d="M14 2V8H20" stroke={theme.accent} strokeWidth="1.5" />
                    </svg>
                  </div>

                  <div>
                    <div style={{ fontSize: 15, fontWeight: 500 }}>{doc.name}</div>
                    <div className="mono" style={{ fontSize: 11, color: theme.text3 }}>
                      {doc.size}
                      {doc.docId ? ` · ${doc.docId}` : ''}
                    </div>
                  </div>
                </div>

                <div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
                  {doc.downloadUrl && (
                    <a
                      href={doc.downloadUrl}
                      target="_blank"
                      rel="noreferrer"
                      style={{ fontSize: 12, color: theme.accent, textDecoration: 'none' }}
                    >
                      下载
                    </a>
                  )}
                  <div
                    className="mono"
                    style={{
                      fontSize: 12,
                      padding: '6px 12px',
                      background: theme.bgHover,
                      borderRadius: 6,
                      color: theme.text2,
                    }}
                  >
                    {doc.status === 'parsing' ? '处理中...' : `${doc.chunks} chunks`}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div>
          <h2
            style={{
              fontSize: 14,
              fontWeight: 600,
              color: theme.accent,
              marginBottom: 20,
              letterSpacing: '1px',
            }}
          >
            文档管理内法规检索
          </h2>

          <div style={{ display: 'flex', gap: 10, marginBottom: 16 }}>
            <input
              value={searchQuery}
              onChange={(event) => setSearchQuery(event.target.value)}
              onKeyDown={(event) => {
                if (event.key === 'Enter') {
                  void runSearch(searchQuery);
                }
              }}
              placeholder="输入法规关键词、条款或制度主题"
              style={{
                flex: 1,
                padding: 12,
                fontSize: 14,
                background: theme.bgCard,
                border: `1px solid ${theme.border}`,
                borderRadius: 8,
                color: theme.text,
                outline: 'none',
              }}
            />
            <button
              onClick={() => void runSearch(searchQuery)}
              disabled={searchLoading || !searchQuery.trim()}
              style={{
                padding: '12px 18px',
                fontSize: 13,
                fontWeight: 600,
                background: searchLoading || !searchQuery.trim() ? theme.bgHover : theme.gradientAccent,
                color: searchLoading || !searchQuery.trim() ? theme.text3 : '#fff',
                border: 'none',
                borderRadius: 8,
                cursor: searchLoading || !searchQuery.trim() ? 'not-allowed' : 'pointer',
              }}
            >
              检索
            </button>
          </div>

          {searchError && (
            <div style={{ marginBottom: 12, fontSize: 13, color: '#d64545' }}>
              {searchError}
            </div>
          )}

          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {searchResults.map((item) => (
              <div
                key={`${item.id}-${item.file}`}
                style={{
                  padding: 18,
                  background: theme.bgCard,
                  borderRadius: 12,
                  border: `1px solid ${theme.border}`,
                  boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
                }}
              >
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, marginBottom: 6 }}>
                  <div style={{ fontSize: 14, fontWeight: 600, color: theme.text }}>{item.file}</div>
                  <div className="mono" style={{ fontSize: 11, color: theme.accent }}>
                    {(item.score * 100).toFixed(1)}%
                  </div>
                </div>

                <div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 8 }}>
                  {item.clause}
                  {item.tags.length > 0 ? ` · ${item.tags.join(' · ')}` : ''}
                </div>

                <div style={{ fontSize: 12, color: theme.text2, lineHeight: 1.6 }}>{item.content}</div>
              </div>
            ))}

            {!searchLoading && searchResults.length === 0 && (
              <div
                style={{
                  padding: 24,
                  borderRadius: 12,
                  background: theme.bgCard,
                  border: `1px solid ${theme.border}`,
                  textAlign: 'center',
                  color: theme.text3,
                }}
              >
                暂无检索结果
              </div>
            )}
          </div>
        </div>
      </section>
    </Content>
  );
};
