import { useState, useEffect, useRef } from "react";
import { useLoaderData, useActionData, useNavigate, Form } from "@remix-run/react";
import { redirect, type ActionFunctionArgs, type LoaderFunctionArgs, type MetaFunction } from "@remix-run/node";
import { Card } from "~/components/ui/Card";
import { Button } from "~/components/ui/Button";
import { usePermission } from "~/hooks/usePermission";
import documentEditStyles from "~/styles/pages/documents_edit.css?url";
import { getDocument, updateDocument } from "~/api/files/documents";
import { getDocumentTypes } from "~/api/document-types/document-types";
import { FileTag } from "~/components/ui/FileTag";
import { toastService } from "~/components/ui/Toast";
import { Document, Page , pdfjs } from "react-pdf";
import { DOCUMENT_URL } from "~/api/axios-client";

pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';

export function links() {
  return [{ rel: "stylesheet", href: documentEditStyles }];
}

export const meta: MetaFunction = () => {
  return [
    { title: "修改文档 - 中国烟草AI合同及卷宗审核系统" },
    { name: "description", content: "修改文档信息，包括文档类型、编号、状态和备注信息等" }
  ];
};

export const handle = {
  breadcrumb: "文档编辑"
};

// 定义action返回数据类型
export interface ActionData {
  success?: boolean;
  error?: string;
  fieldErrors?: {
    document_number?: string;
    audit_status?: string;
    remark?: string;
    general?: string;
  };
  values?: Record<string, string>;
}

// 文档审核状态定义
enum DocumentAuditStatus {
  FAIL = -1,
  PASS = 1,
  WAITING = 0,
  PROCESSING = 2
}

// 文档状态对应的中文标签
const STATUS_LABELS: Record<DocumentAuditStatus, string> = {
  [DocumentAuditStatus.FAIL]: "不通过",
  [DocumentAuditStatus.WAITING]: "待审核",
  [DocumentAuditStatus.PASS]: "通过",
  [DocumentAuditStatus.PROCESSING]: "审核中"
};

// 文档状态样式配置
const STATUS_STYLES: Record<number, { color: string; icon: string }> = {
  [-1]: { color: "red", icon: "ri-close-line" },
  [0]: { color: "blue", icon: "ri-time-line" },
  [1]: { color: "green", icon: "ri-check-line" },
  [2]: { color: "yellow", icon: "ri-alert-line" },
  [3]: { color: "purple", icon: "ri-search-line" }
};

// 格式化文件大小
function formatFileSize(bytes: number): string {
  if (bytes === 0) return "0 Bytes";
  
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}

// Loader函数
export async function loader({ request }: LoaderFunctionArgs) {
  try {
    // 获取用户会话信息
    const { getUserSession } = await import("~/api/login/auth.server");
    const { userInfo, frontendJWT } = await getUserSession(request);
    
    if (!userInfo?.user_id) {
      throw new Response("用户身份验证失败", { status: 401 });
    }
    
    const userId = userInfo.user_id.toString();
    
    // 从URL查询参数获取文档ID
    const url = new URL(request.url);
    const id = url.searchParams.get("id");
    
    if (!id) {
      throw new Response("缺少文档ID", { status: 400 });
    }
    
    // 并行获取文档详情和文档类型列表
    const [documentResponse, documentTypesResponse] = await Promise.all([
      getDocument(id, userId, frontendJWT),
      getDocumentTypes({ pageSize: 500 }, frontendJWT)
    ]);
    
    if (documentResponse.error) {
      throw new Response(documentResponse.error, { status: documentResponse.status || 404 });
    }
    
    if (documentTypesResponse.error) {
      console.error("获取文档类型列表失败:", documentTypesResponse.error);
    }
    
    return Response.json({
      document: documentResponse.data,
      documentTypes: documentTypesResponse.data?.types || [],
      frontendJWT: frontendJWT
    });
  } catch (error) {
    console.error("加载文档数据失败:", error);
    throw new Response("加载文档数据失败", { status: 500 });
  }
}

// Action函数处理表单提交
export async function action({ request }: ActionFunctionArgs) {
  // 获取用户会话信息
  const { getUserSession } = await import("~/api/login/auth.server");
  const { userInfo, frontendJWT } = await getUserSession(request);
  
  if (!userInfo?.user_id) {
    return Response.json({ error: "用户身份验证失败" }, { status: 401 });
  }
  
  const userId = userInfo.user_id.toString();
  
  // 从URL查询参数获取文档ID
  const url = new URL(request.url);
  const id = url.searchParams.get("id");
  
  if (!id) {
    return Response.json({ error: "缺少文档ID" }, { status: 400 });
  }
  
  try {
    const formData = await request.formData();
    
    // 从表单数据中提取字段
    // const type = formData.get("type_id") as string;
    const documentNumber = formData.get("document_number") as string;
    const auditStatus = parseInt(formData.get("audit_status") as string);
    const isTest = formData.get("is_test_document") === "on";
    const remark = formData.get("remark") as string;

    // 表单验证
    const errors: ActionData["fieldErrors"] = {};
    
    if (isNaN(auditStatus)) {
      errors.audit_status = "审核状态必须选择";
    }
    
    if (Object.keys(errors).length > 0) {
      return Response.json({ 
        fieldErrors: errors,
        values: Object.fromEntries(formData) as Record<string, string>
      }, { status: 400 });
    }
    
    // 更新文档
    const updateResponse = await updateDocument(id, {
      // type,
      documentNumber,
      auditStatus,
      isTest,
      remark
    }, userId, frontendJWT);
    
    if (updateResponse.error) {
      console.error('更新文档失败:', updateResponse.error);
      return Response.json({ 
        error: updateResponse.error,
        fieldErrors: {
          general: "更新文档失败，请检查提交的数据是否正确"
        },
        values: Object.fromEntries(formData) as Record<string, string>
      }, { status: updateResponse.status || 500 });
    }
    
    toastService.success('更新文档成功');
    return redirect("/documents/list");
  } catch (error) {
    console.error("更新文档失败2:", error);
    return Response.json({ 
      error: "更新文档失败",
      fieldErrors: {
        general: error instanceof Error ? error.message : "发生未知错误"
      }
    }, { status: 500 });
  }
}

// 文档编辑页面组件
export default function DocumentEdit() {
  const { document: documentData, documentTypes } = useLoaderData<typeof loader>();
  const actionData = useActionData<ActionData>();
  const navigate = useNavigate();
  const [numPages, setNumPages] = useState(0);
  const [loadError, setLoadError] = useState<string | null>(null);
  const formRef = useRef<HTMLFormElement>(null);

  // 权限控制
  const { hasPermission } = usePermission();
  const canUpdate = hasPermission('document:document:update');
  
  // 表单状态管理 - 使用受控组件
  const [formValues, setFormValues] = useState({
    documentNumber: documentData.documentNumber || "",
    auditStatus: documentData.auditStatus,
    isTest: documentData.isTest || false,
    remark: documentData.remark || ""
  });
  
  // 表单验证错误状态
  const [formErrors, setFormErrors] = useState<{
    documentNumber?: string;
    auditStatus?: string;
    remark?: string;
    general?: string;
  }>({});
  
  // 字段是否被触摸过（用于确定何时显示错误）
  const [touchedFields, setTouchedFields] = useState({
    documentNumber: false,
    auditStatus: false,
    remark: false
  });
  
  // 从 actionData 初始化表单错误
  useEffect(() => {
    if (actionData?.fieldErrors) {
      // general 错误使用 toast 提示
      if (actionData.fieldErrors.general) {
        toastService.error(actionData.fieldErrors.general);
      }
      // 其他字段错误设置到 formErrors
      setFormErrors(actionData.fieldErrors);
    }
  }, [actionData]);
  
  // 验证表单字段
  const validateField = (field: string, value: string | number | undefined): string => {
    switch (field) {
      case 'auditStatus': {
        const statusValue = typeof value === 'string' ? parseInt(value) : value;
        return statusValue === undefined || isNaN(statusValue as number) ? "审核状态必须选择" : "";
      }
      default:
        return "";
    }
  };
  
  // 处理字段改变
  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
    const { name, value, type } = e.target;
    
    if (type === 'checkbox') {
      const checked = (e.target as HTMLInputElement).checked;
      setFormValues(prev => ({
        ...prev,
        [name === 'is_test_document' ? 'isTest' : name]: checked
      }));
    } else {
      setFormValues(prev => ({
        ...prev,
        [name === 'document_number' ? 'documentNumber' : 
         name === 'audit_status' ? 'auditStatus' : name]: 
         name === 'audit_status' ? (parseInt(value)) : value
      }));
    }
    
    // 标记字段为已触摸
    if (name === 'document_number' || name === 'audit_status' || name === 'remark') {
      const fieldName = name === 'document_number' ? 'documentNumber' : 
                        name === 'audit_status' ? 'auditStatus' : name;
      setTouchedFields(prev => ({
        ...prev,
        [fieldName]: true
      }));
    }
    
    // 实时验证
    if (name === 'audit_status') {
      const statusValue = parseInt(value);
      const error = validateField('auditStatus', statusValue);
      setFormErrors(prev => ({
        ...prev,
        auditStatus: error
      }));
    }
  };
  
  // 处理表单提交前验证
  const handleBeforeSubmit = (e: React.FormEvent) => {
    // 标记所有字段为已触摸
    setTouchedFields({
      documentNumber: true,
      auditStatus: true,
      remark: true
    });
    
    // 验证所有字段
    const errors = {
      auditStatus: validateField('auditStatus', formValues.auditStatus)
    };
    
    setFormErrors(errors);
    
    // 如果有错误，阻止提交
    if (errors.auditStatus) {
      toastService.error('审核状态不能为空');
      e.preventDefault();
    }
  };

  const onDocumentLoadSuccess = ({numPages}: {numPages: number}) => {
    setNumPages(numPages);
    // console.log('文档加载成功', numPages);
  }

  const renderDocumentContent = () => {
    return (
      <div className="preview-content relative overflow-y-auto max-h-[1000px]">
        <Document
          file={`/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}`}
          onLoadSuccess={onDocumentLoadSuccess}
          onLoadError={(error) => {
            console.error("PDF加载错误:", error);
            setLoadError("PDF文档加载失败：" + (error.message || "未知错误"));
          }}
          className="flex flex-col items-center w-full"
          error={<div className="text-red-500">PDF文档加载失败，请检查链接或网络连接。</div>}
          noData={<div>无数据</div>}
          loading={<div className="text-center py-10">PDF加载中...</div>}
        >
          {renderAllPages()}
        </Document>
      </div>
    )
  }

  const renderAllPages = () => {
    // 如果还没有获取到PDF总页数，返回null
    if (!numPages) return null;
    
    // 用于存储所有页面组件的数组
    const pages = [];
    const styles = {
      pageContainer: {
        display: 'flex',
        flexDirection: 'column' as const,
        alignItems: 'center',
        width: '100%',
        position: 'relative' as const,
      }
    };
    
    // 遍历每一页，生成对应的页面组件
    for (let i = 1; i <= numPages; i++) {
      // 为每一页创建组件
      pages.push(
        <div key={i} id={`page-${i}`} style={styles.pageContainer}>
          {/* 页码标识，显示在页面上方 */}
          <div className="text-center text-gray-500 text-sm mb-2">第 {i} 页</div>
          
          {/* 页面容器，应用缩放变换，设置相对定位用于放置评查点高亮 */}
          <div 
            className="page-wrapper flex justify-center" 
            style={{ 
              position: 'relative',
              maxWidth: '100%',
            }}
          >
            {/* 渲染PDF页面组件 */}
            <Page
              pageNumber={i}                               // 当前页码
              renderTextLayer={false}                       // 停用文本层，使文本可选择
              renderAnnotationLayer={false}                 // 停用注释层，显示PDF内置注释
              className="border border-gray-300 shadow-md" // 添加边框和阴影样式
            />
          </div>
        </div>
      );
    }
    
    // 返回所有页面组件数组
    return pages;
  };

  // 定义类型
  interface DocType {
    id: string | number;
    name: string;
  }
  
  // 获取文档类型名称
  const getDocumentTypeName = (typeId: string): string => {
    const docType = documentTypes.find((type: DocType) => type.id.toString() === typeId);
    return docType ? docType.name : "未知类型";
  };
  
  // 渲染状态徽章
  const renderStatusBadge = (status: number) => {
    const style = STATUS_STYLES[status] || STATUS_STYLES[0];
    const label = STATUS_LABELS[status as DocumentAuditStatus] || STATUS_LABELS[DocumentAuditStatus.WAITING];
    
    return (
      <span className={`status-badge bg-${style.color}-100 text-${style.color}-800`}>
        <i className={`${style.icon} mr-1`}></i>
        {label}
      </span>
    );
  };

  // 下载文档
  const downloadDocument = async () => {
    try {
      // 使用 PDF 代理路由获取文件，自动添加 JWT 认证（默认行为是下载）
      const downloadUrl = `/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}`;

      // 使用fetch获取文件内容
      const response = await fetch(downloadUrl);
      if (!response.ok) {
        throw new Error(`下载失败: ${response.status} ${response.statusText}`);
      }

      // 将响应转换为Blob
      const blob = await response.blob();

      // 创建Blob URL
      const blobUrl = URL.createObjectURL(blob);

      // 创建一个隐藏的a标签并点击它
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = blobUrl;
      // 从路径中获取文件名
      const fileName = documentData.path.split('/').pop() || documentData.name;
      a.download = decodeURIComponent(fileName);
      document.body.appendChild(a);
      a.click();

      // 清理
      setTimeout(() => {
        document.body.removeChild(a);
        URL.revokeObjectURL(blobUrl);
      }, 100);

      toastService.success('文件下载成功');
    } catch (error) {
      console.error('下载文件失败:', error);
      toastService.error(`下载文件失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  };

  // 在新窗口打开文档预览
  const openPreview = () => {
    // 使用 PDF 代理路由，自动添加 JWT 认证，添加 preview 参数实现预览
    const previewUrl = `/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}&preview=true`;
    window.open(previewUrl, '_blank');
  };
  
  return (
    <div className="document-edit-page">
      {/* 页面头部 */}
      <div className="page-header">
        <h2 className="page-title">修改文档信息</h2>
        <div>
          <Button
            type="default"
            icon="ri-arrow-left-line"
            onClick={() => navigate("/documents/list")}
            className="mr-2"
          >
            返回列表
          </Button>
          {/* 保存修改按钮 - 需要 document:document:update 权限 */}
          {canUpdate && (
            <Button
              type="primary"
              icon="ri-save-line"
              form="edit-form"
            >
              保存修改
            </Button>
          )}
        </div>
      </div>
      
      {/* 文档信息 */}
      <Card className="mb-4">
        <div className="document-info">
          <div className="document-icon">
            <FileTag 
              extension={documentData.fileType}
              showIcon={true} 
              showText={false} 
              showBackground={false}
              size="lg"
            />
          </div>
          <div className="document-details">
            <div className="document-name">{documentData.name}</div>
            <div className="document-meta">
              <div className="meta-item">
                <i className="ri-file-list-line"></i>
                <span>{getDocumentTypeName(documentData.type)}</span>
              </div>
              <div className="meta-item">
                <i className="ri-time-line"></i>
                <span>{documentData.uploadTime}</span>
              </div>
              <div className="meta-item">
                <i className="ri-hard-drive-line"></i>
                <span>{formatFileSize(documentData.size)}</span>
              </div>
              <div className="meta-item">
                {renderStatusBadge(documentData.auditStatus)}
              </div>
            </div>
          </div>
        </div>
        
        <div className="alert alert-info mb-4">
          <i className="ri-information-line mr-2"></i> 您可以修改此文档的基本信息，但不能更改文档内容。如需修改内容，请删除后重新上传新文档。
        </div>

        <Form id="edit-form" method="post" ref={formRef} onSubmit={handleBeforeSubmit}>
          <div className="grid grid-cols-2 gap-6">
            <div className="form-group">
              <label htmlFor="type-id" className="form-label">文档类型 <span className="text-red-500">*</span></label>
              <select
                id="type-id"
                name="type_id"
                className="form-select"
                value={documentData.type}
                disabled={true}
                required
              >
                {documentTypes.map((type: DocType) => (
                  <option key={type.id} value={type.id}>{type.name}</option>
                ))}
              </select>
              <div className="text-sm text-secondary mt-1">更改文档类型将重新应用对应的评查规则</div>
            </div>
            
            <div className="form-group">
              <label htmlFor="document-number" className="form-label">文档编号</label>
              <input 
                type="text" 
                id="document-number"
                name="document_number"
                className="form-input" 
                placeholder="请输入合同编号、许可证号等" 
                value={formValues.documentNumber}
                onChange={handleChange}
              />
              <div className="text-sm text-secondary mt-1">如无编号可留空</div>
            </div>
            
            <div className="form-group">
              <label htmlFor="audit-status" className="form-label">审核状态 <span className="text-red-500">*</span></label>
              <select 
                id="audit-status"
                name="audit_status"
                className={`form-select ${touchedFields.auditStatus && formErrors.auditStatus ? 'error' : ''}`}
                value={formValues.auditStatus}
                onChange={handleChange}
                required
              >
                {/* <option value='全部'>请选择审核状态</option> */}
                <option value={DocumentAuditStatus.WAITING}>{STATUS_LABELS[DocumentAuditStatus.WAITING]}</option>
                <option value={DocumentAuditStatus.PROCESSING}>{STATUS_LABELS[DocumentAuditStatus.PROCESSING]}</option>
                <option value={DocumentAuditStatus.PASS}>{STATUS_LABELS[DocumentAuditStatus.PASS]}</option>
                <option value={DocumentAuditStatus.FAIL}>{STATUS_LABELS[DocumentAuditStatus.FAIL]}</option>
              </select>
              <div className="text-sm text-secondary mt-1">更改状态可能会影响此文档在列表中的显示和排序</div>
              {touchedFields.auditStatus && formErrors.auditStatus && (
                <div className="text-red-500 text-sm mt-1">{formErrors.auditStatus}</div>
              )}
            </div>
            
            <div className="form-group">
              <div className="form-label">文档属性</div>
              <div className="flex items-center mt-2">
                <label className="switch mr-2" htmlFor="is-test-document">
                  <input 
                    type="checkbox" 
                    id="is-test-document"
                    name="is_test_document"
                    checked={formValues.isTest}
                    onChange={handleChange}
                  />
                  <span className="slider"></span>
                  <span className="sr-only">标记为测试文档</span>
                </label>
                <span>标记为测试文档（不计入正式统计）</span>
              </div>
            </div>
            
            <div className="form-group col-span-2">
              <label htmlFor="remark" className="form-label">备注信息</label>
              <textarea 
                id="remark"
                name="remark"
                className="form-textarea" 
                placeholder="可输入文档的相关描述或备注信息" 
                rows={3}
                value={formValues.remark}
                onChange={handleChange}
              ></textarea>
            </div>
          </div>
        </Form>
      </Card>
      
      {/* 文档预览 */}
      { false && <Card 
        title="文档预览"
        className="mb-4"
      >
        <div className="document-preview">
          <div className="preview-toolbar">
            <div className="flex items-center">
              <i className={`ri-file-${documentData.fileType}-line text-${documentData.fileType === 'pdf' ? 'red' : 'blue'}-500 mr-1`}></i>
              <span>{documentData.name}</span>
            </div>
            <div>
              <Button 
                type="default" 
                size="small"
                icon="ri-download-line"
                className="mr-2"
                onClick={downloadDocument}
              >
                下载
              </Button>
              <Button 
                type="primary" 
                size="small"
                icon="ri-external-link-line"
                onClick={openPreview}
              >
                在新窗口打开
              </Button>
            </div>
          </div>
          {/* 预览窗口 */} 
          {loadError ? (
            <div className="text-red-500">
              {loadError}
            </div>
          ) : (
            renderDocumentContent()
          )}
        </div>
      </Card>
      }

      
      {/* 修改历史 */}
      <Card title="修改历史" className="hidden">
        <div className="history-timeline">
          {[
            {
              time: "2023-10-15 15:30",
              user: "系统",
              action: "创建了此文档",
              details: `首次上传文档，文档类型：${getDocumentTypeName(documentData.type)}，状态：待审核`
            },
            {
              time: "2023-10-15 16:45",
              user: "张三",
              action: "启动了文档审核",
              details: "状态由'待审核'变更为'审核中'"
            },
            {
              time: "2023-10-15 17:20",
              user: "系统",
              action: "完成了文档审核",
              details: "状态由'审核中'变更为'通过'，未发现问题"
            },
            {
              time: "2023-10-16 09:10",
              user: "李四",
              action: "修改了文档属性",
              details: "添加了备注信息，完善了文档编号"
            }
          ].map((item, index) => (
            <div className="timeline-item" key={`${item.time}-${index}`}>
              <div className="timeline-time">{item.time}</div>
              <div className="timeline-content">
                <div><strong>{item.user}</strong> {item.action}</div>
                <div className="text-xs text-secondary mt-1">{item.details}</div>
              </div>
            </div>
          ))}
        </div>
      </Card>
    </div>
  );
}

// 错误边界
export function ErrorBoundary() {
  return (
    <div className="error-container">
      <h1 className="text-xl font-bold text-red-500 mb-4">出错了</h1>
      <p className="mb-4">文档编辑页面加载失败。请检查文档ID是否正确，或稍后重试。</p>
      <Button
        type="primary"
        to="/documents/list"
      >
        返回文档列表
      </Button>
    </div>
  );
}
