import { type LoaderFunctionArgs, type MetaFunction } from '@remix-run/node';
import { Link, useLoaderData, useSearchParams } from '@remix-run/react';
import type React from 'react';
import { Button } from '~/components/ui/Button';
import { Card } from '~/components/ui/Card';
import { FilterPanel, FilterSelect, SearchFilter } from '~/components/ui/FilterPanel';
import { Pagination } from '~/components/ui/Pagination';
import { Table } from '~/components/ui/Table';
import { Tag, type TagColor } from '~/components/ui/Tag';
import { loadRuleConfigPacks } from '~/utils/rules-config-packs.server';
import type { RuleSummary, RuleYamlPack } from '~/utils/rules-yaml-mock.server';
import styles from '~/styles/pages/rules_test.css?url';

export const links = () => [
  { rel: 'stylesheet', href: styles }
];

export const meta: MetaFunction = () => [
  { title: '规则 YAML 列表 - 智慧法务' }
];

export const handle = {
  breadcrumb: '评查点列表'
};

type RuleRow = RuleSummary & {
  rowId: string;
  packId: string;
  documentType: string;
  moduleType: string;
  mainType: string;
  subtype: string;
  yamlName: string;
  yamlStatus: RuleYamlPack['sourceStatus'];
};

type LoaderData = {
  rows: RuleRow[];
  packs: RuleYamlPack[];
  filters: {
    documentType: string;
    mainType: string;
    subtype: string;
    ruleGroup: string;
    keyword: string;
    page: number;
    pageSize: number;
  };
  totalCount: number;
  currentPage: number;
  pageSize: number;
  options: {
    documentTypes: string[];
    mainTypes: string[];
    subtypes: string[];
    ruleGroups: string[];
  };
};

function unique(values: string[]): string[] {
  return Array.from(new Set(values.filter(Boolean)));
}

function resolveDocumentScope(pack: Pick<RuleYamlPack, 'documentType' | 'mainType' | 'moduleType'>): string {
  const values = [pack.documentType, pack.mainType, pack.moduleType].join(' ');
  if (values.includes('合同')) return '合同';
  if (values.includes('案卷') || values.includes('卷宗') || values.includes('行政处罚') || values.includes('行政许可')) {
    return '案卷';
  }
  if (values.includes('公文')) return '内部公文';
  return pack.documentType || pack.mainType || pack.moduleType || '未分类';
}

function resolveBusinessType(pack: Pick<RuleYamlPack, 'businessType' | 'mainType'>): string {
  return pack.businessType || pack.mainType || '';
}

function riskColor(risk: string): TagColor {
  if (risk === 'high') return 'red';
  if (risk === 'medium') return 'orange';
  if (risk === 'low') return 'green';
  return 'gray';
}

export async function loader({ request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const requestedMainType = url.searchParams.get('mainType') || url.searchParams.get('ruleTypeName') || '';
  const requestedSubtype = url.searchParams.get('subtype') || url.searchParams.get('documentAttributeType') || '';
  const requestedRuleGroup = url.searchParams.get('ruleGroup') || url.searchParams.getAll('ruleGroups')[0] || '';
  const requestedPage = Number(url.searchParams.get('page') || '1');
  const requestedPageSize = Number(url.searchParams.get('pageSize') || '10');
  const requestedFilters = {
    documentType: url.searchParams.get('documentType') || '',
    mainType: requestedMainType,
    subtype: requestedSubtype,
    ruleGroup: requestedRuleGroup,
    keyword: url.searchParams.get('keyword') || '',
    page: Number.isFinite(requestedPage) && requestedPage > 0 ? requestedPage : 1,
    pageSize: [10, 20, 30, 50].includes(requestedPageSize) ? requestedPageSize : 10
  };

  const packs = await loadRuleConfigPacks(request);
  const packScopes = packs.map(pack => ({
    pack,
    scope: resolveDocumentScope(pack),
  }));
  const documentTypes = unique(packScopes.map(item => item.scope));
  const requestedDocumentType = requestedFilters.documentType;
  const inferredDocumentType = requestedMainType
    ? packScopes.find(item => resolveBusinessType(item.pack) === requestedMainType)?.scope || ''
    : '';
  const currentDocumentType = documentTypes.includes(requestedDocumentType)
    ? requestedDocumentType
    : inferredDocumentType || documentTypes[0] || '';
  const scopedDocumentPacks = packScopes
    .filter(item => item.scope === currentDocumentType)
    .map(item => item.pack);
  const scopedFilters = {
    ...requestedFilters,
    documentType: currentDocumentType,
    mainType: scopedDocumentPacks.some(pack => resolveBusinessType(pack) === requestedFilters.mainType)
      ? requestedFilters.mainType
      : '',
    subtype: scopedDocumentPacks.some(pack =>
      (!requestedFilters.mainType || resolveBusinessType(pack) === requestedFilters.mainType) &&
      pack.subtype === requestedFilters.subtype
    )
      ? requestedFilters.subtype
      : ''
  };
  const scopedByMainTypePacks = scopedDocumentPacks.filter(pack =>
    !scopedFilters.mainType || resolveBusinessType(pack) === scopedFilters.mainType
  );
  const subtypeOptions = unique(scopedByMainTypePacks.map(pack => pack.subtype));
  const ruleGroupSourcePacks = scopedFilters.subtype
    ? scopedByMainTypePacks.filter(pack => pack.subtype === scopedFilters.subtype)
    : subtypeOptions.length <= 1
      ? scopedByMainTypePacks
      : [];
  const ruleGroupOptions = unique(
    ruleGroupSourcePacks.flatMap(pack => pack.rules.map(rule => rule.group))
  ).sort((a, b) => a.localeCompare(b, 'zh-CN'));
  const filters = {
    ...scopedFilters,
    ruleGroup: ruleGroupOptions.includes(requestedFilters.ruleGroup) ? requestedFilters.ruleGroup : ''
  };
  const visiblePacks = scopedDocumentPacks.filter(pack =>
    (!filters.mainType || resolveBusinessType(pack) === filters.mainType) &&
    (!filters.subtype || pack.subtype === filters.subtype)
  );

  const filteredRows: RuleRow[] = visiblePacks.flatMap((pack): RuleRow[] => {
    if (pack.rules.length === 0) {
      return [{
        rowId: `${pack.id}-empty`,
        packId: pack.id,
        documentType: pack.documentType,
        moduleType: pack.moduleType,
        mainType: resolveBusinessType(pack),
        subtype: pack.subtype,
        yamlName: pack.metadata.name || '待配置 YAML',
        yamlStatus: pack.sourceStatus,
        id: `${pack.id}-empty`,
        ruleId: '-',
        name: '暂无规则配置',
        group: '待配置',
        risk: '-',
        score: '-',
        type: '-',
        checkTypes: [],
        logic: '',
        subRules: [],
        subRuleIds: [],
        scope: [],
        dependencies: [],
        stageCount: 0,
        appliesIn: [],
        prompt: '',
        description: '当前文档类型已保留规则列表与 YAML 配置页流程，等待后续接入规则文件。'
      }];
    }

    return pack.rules.map(rule => ({
      ...rule,
      rowId: `${pack.id}-${rule.ruleId || rule.id}`,
      packId: pack.id,
      documentType: pack.documentType,
      moduleType: pack.moduleType,
      mainType: resolveBusinessType(pack),
      subtype: pack.subtype,
      yamlName: pack.metadata.name,
      yamlStatus: pack.sourceStatus
    }));
  }).filter(row => {
    if (filters.ruleGroup && row.group !== filters.ruleGroup) {
      return false;
    }
    if (!filters.keyword) return true;
    return [row.ruleId, row.name, row.group, row.yamlName, row.subtype]
      .some(value => value.toLowerCase().includes(filters.keyword.toLowerCase()));
  });
  const totalCount = filteredRows.length;
  const totalPages = Math.max(1, Math.ceil(totalCount / filters.pageSize));
  const currentPage = Math.min(filters.page, totalPages);
  const startIndex = (currentPage - 1) * filters.pageSize;
  const rows = filteredRows.slice(startIndex, startIndex + filters.pageSize);

  return Response.json({
    rows,
    packs,
    filters: {
      ...filters,
      page: currentPage
    },
    totalCount,
    currentPage,
    pageSize: filters.pageSize,
    options: {
      documentTypes,
      mainTypes: unique(scopedDocumentPacks.map(pack => resolveBusinessType(pack))),
      subtypes: subtypeOptions,
      ruleGroups: ruleGroupOptions
    }
  } satisfies LoaderData);
}

export default function RulesTestList() {
  const { rows, filters, options, totalCount, currentPage, pageSize } = useLoaderData<typeof loader>() as LoaderData;
  const [searchParams, setSearchParams] = useSearchParams();

  const updateParams = (updates: Record<string, string | number | undefined>, resetPage = true) => {
    const nextParams = new URLSearchParams(searchParams);

    Object.entries(updates).forEach(([key, value]) => {
      if (value === undefined || value === '') {
        nextParams.delete(key);
        return;
      }
      nextParams.set(key, String(value));
    });

    if (resetPage) {
      nextParams.set('page', '1');
    }

    setSearchParams(nextParams);
  };

  const handleFilterChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const { name, value } = event.target;
    if (name === 'mainType') {
      updateParams({
        mainType: value,
        ruleTypeName: undefined,
        subtype: undefined,
        documentAttributeType: undefined,
        ruleGroup: undefined,
      });
      return;
    }
    if (name === 'subtype') {
      updateParams({ subtype: value, documentAttributeType: undefined, ruleGroup: undefined });
      return;
    }
    updateParams({ [name]: value });
  };

  const handleSearch = (keyword: string) => {
    updateParams({ keyword });
  };

  const handleReset = () => {
    const nextParams = new URLSearchParams(searchParams);
    ['mainType', 'ruleTypeName', 'ruleGroup', 'subtype', 'documentAttributeType', 'keyword', 'page'].forEach(key => nextParams.delete(key));
    nextParams.set('page', '1');
    setSearchParams(nextParams);
  };

  const handlePageChange = (page: number) => {
    updateParams({ page }, false);
  };

  const handlePageSizeChange = (nextPageSize: number) => {
    updateParams({ pageSize: nextPageSize, page: 1 }, false);
  };

  const columns = [
    {
      title: '规则',
      key: 'rule',
      width: '24%',
      render: (_: unknown, record: RuleRow) => (
        <div className="rule-name">
          <strong>{record.name}</strong>
          <span>{record.ruleId}</span>
        </div>
      )
    },
    {
      title: '子分类',
      key: 'subtype',
      width: '12%',
      align: 'center' as const,
      render: (_: unknown, record: RuleRow) => (
        <div className="inline-tags">
          <Tag color="blue" size="sm">{record.subtype}</Tag>
        </div>
      )
    },
    {
      title: '规则组',
      dataIndex: 'group' as keyof RuleRow,
      key: 'group',
      width: '14%',
      align: 'center' as const
    },
    {
      title: '风险',
      key: 'risk',
      width: '8%',
      align: 'center' as const,
      render: (_: unknown, record: RuleRow) => (
        <Tag color={riskColor(record.risk)} size="sm">{record.risk}</Tag>
      )
    },
    {
      title: '分值',
      key: 'score',
      width: '8%',
      align: 'center' as const,
      render: (_: unknown, record: RuleRow) => (
        <Tag color="gray" size="sm">{record.score}</Tag>
      )
    },
    {
      title: '依赖字段',
      key: 'dependencies',
      width: '20%',
      render: (_: unknown, record: RuleRow) => (
        <span>{record.dependencies.length > 0 ? record.dependencies.slice(0, 3).join('、') : '-'}</span>
      )
    },
    {
      title: '操作',
      key: 'operation',
      width: '14%',
      align: 'center' as const,
      render: (_: unknown, record: RuleRow) => (
        <Link className="operation-btn" to={`/rulesTest/detail?packId=${encodeURIComponent(record.packId)}&ruleId=${encodeURIComponent(record.ruleId || record.id)}`}>
          <i className="ri-settings-3-line"></i> 配置
        </Link>
      )
    }
  ];

  return (
    <div className="rules-test-page rules-page">
      <div className="rules-test-list-shell">
        <div className="rules-list-header">
          <div className="rules-list-title">
            <h2>评查点管理</h2>
            <div className="rules-list-total">
              <i className="ri-file-list-3-line"></i>
              <span>总评查点数：</span>
              <strong>{totalCount}</strong>
            </div>
          </div>
        </div>

        <FilterPanel
          className="rules-test-filter-panel px-3 py-3"
          noActionDivider={true}
          actions={
            <Button type="default" icon="ri-refresh-line" onClick={handleReset} className="mr-2 hover:!border-gray-300">
              重置
            </Button>
          }
        >
          <FilterSelect
            label="业务类型"
            name="mainType"
            value={filters.mainType}
            options={options.mainTypes.map(mainType => ({ value: mainType, label: mainType }))}
            onChange={handleFilterChange}
            className="mr-3 w-[18%]"
            placeholder="全部"
          />

          <FilterSelect
            label="子类型"
            name="subtype"
            value={filters.subtype}
            options={options.subtypes.map(subtype => ({ value: subtype, label: subtype }))}
            onChange={handleFilterChange}
            className="mr-3 w-[18%]"
            placeholder={filters.mainType || options.mainTypes.length <= 1 ? '全部' : '请先选择业务类型'}
          />

          <FilterSelect
            label="所属规则组"
            name="ruleGroup"
            value={filters.ruleGroup}
            options={options.ruleGroups.map(group => ({ value: group, label: group }))}
            onChange={handleFilterChange}
            className="mr-3 w-[22%]"
            disabled={options.ruleGroups.length === 0}
            placeholder={filters.subtype || options.subtypes.length <= 1 ? '全部' : '请先选择子类型'}
          />

          <SearchFilter
            key={filters.keyword}
            label="搜索"
            placeholder="输入评查点名称或编码"
            value={filters.keyword}
            buttonText="搜索"
            onSearch={handleSearch}
            className="min-w-[200px] flex-1"
          />
        </FilterPanel>

        <Card className="ant-card">
          <Table
            className="rules-test-table rules-table"
            columns={columns}
            dataSource={rows}
            rowKey="rowId"
            scroll={{ y: 700 }}
            emptyText={<div className="empty-state">暂无规则。当前类型的规则列表流程已保留，可进入配置页查看空 YAML 模板。</div>}
          />
          {totalCount > 0 && (
            <Pagination
              currentPage={currentPage}
              total={totalCount}
              pageSize={pageSize}
              onChange={handlePageChange}
              onPageSizeChange={handlePageSizeChange}
              showTotal={true}
              showPageSizeChanger={true}
              pageSizeOptions={[10, 20, 30, 50]}
            />
          )}
        </Card>
      </div>
    </div>
  );
}
