/**
 * @name 客户管理
 */

import '../vehicle-management/style.css';
import './styles/index.css';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { Download, FileUp, Plus, Tags } from 'lucide-react';
import {
  type AnnotationDirectoryRouteNode,
  type AnnotationSourceDocument,
  type AnnotationViewerOptions
} from '@axhub/annotation';
import { PrototypeAnnotationHost } from '../../common/prototype-annotation-host';
import seedCustomers from './data/customers.json';
import { FilterPanel } from './components/FilterPanel';
import { CustomerTable } from './components/CustomerTable';
import { CreatePage } from './pages/CreatePage';
import { RiskTagDrawer } from './components/RiskTagDrawer';
import { BatchRiskTagModal } from './components/BatchRiskTagModal';
import { TablePagination } from '../vehicle-management/components/TablePagination';
import {
  EMPTY_CREATE_FORM,
  EMPTY_FILTERS,
  type CustomerCreateForm,
  type CustomerFilters,
  type CustomerPageId,
  type CustomerRecord,
} from './types';
import type { CustomerRiskTag, MockUser, RiskTagApplyForm } from './types/riskTag';
import { applyFilters } from './utils/filters';
import {
  buildApplyLog,
  buildApplyTag,
  buildApprovalLog,
  buildRemoveLog,
  buildSeedRiskTags,
  formatNow,
  INITIAL_OPERATION_LOGS,
  syncRecordLabels,
  todayDate,
} from './utils/riskTagStore';
import { canApplyRiskTagByName, canBatchTag, canManageRiskTags, canRemoveRiskTag, MOCK_USERS } from './utils/permissions';
import annotationSourceDocument from './annotation-source.json';

const DEFAULT_PAGE_SIZE = 10;

type NavigationRef = {
  openCreate?: () => void;
  backToList?: () => void;
};

function validateCreateForm(form: CustomerCreateForm): string | null {
  if (!form.customerType) return '请选择客户类型';
  if (!form.customerName.trim()) return '请输入客户全称';
  if (!form.cityProvince || !form.cityName) return '请填写通讯地址以识别所属城市';
  if (!form.department) return '请选择业务负责部门';
  if (!form.manager) return '请选择业务负责人员';
  if (!form.invoiceTitle.trim()) return '请填写发票抬头';
  if (!form.taxId.trim()) return '请输入纳税人识别号';
  if (!form.bankName.trim()) return '请输入开户银行';
  return null;
}

export default function CustomerManagementApp() {
  const seedRecords = seedCustomers as CustomerRecord[];
  const initialRiskTags = useMemo(() => buildSeedRiskTags(seedRecords), []);

  const [records, setRecords] = useState<CustomerRecord[]>(() =>
    syncRecordLabels(seedRecords, initialRiskTags),
  );
  const [riskTagsByCustomer, setRiskTagsByCustomer] = useState<Record<string, CustomerRiskTag[]>>(initialRiskTags);
  const [operationLogs, setOperationLogs] = useState(INITIAL_OPERATION_LOGS);
  const [currentUser, setCurrentUser] = useState<MockUser>(MOCK_USERS[0]);

  const [view, setView] = useState<CustomerPageId>('list');
  const [pendingFilters, setPendingFilters] = useState<CustomerFilters>(EMPTY_FILTERS);
  const [appliedFilters, setAppliedFilters] = useState<CustomerFilters>(EMPTY_FILTERS);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [createForm, setCreateForm] = useState<CustomerCreateForm>(EMPTY_CREATE_FORM);
  const [toast, setToast] = useState('');
  const [tagDrawerRecord, setTagDrawerRecord] = useState<CustomerRecord | null>(null);
  const [batchTagOpen, setBatchTagOpen] = useState(false);
  const navigationRef = useRef<NavigationRef>({});

  const showToast = useCallback((msg: string) => {
    setToast(msg);
    window.setTimeout(() => setToast(''), 3000);
  }, []);

  const refreshRecordLabels = useCallback((nextTags: Record<string, CustomerRiskTag[]>) => {
    setRecords((prev) => syncRecordLabels(prev, nextTags));
  }, []);

  navigationRef.current = {
    openCreate: () => {
      setCreateForm(EMPTY_CREATE_FORM);
      setView('create');
    },
    backToList: () => setView('list'),
  };

  const filtered = useMemo(
    () => applyFilters(records, appliedFilters),
    [records, appliedFilters],
  );

  const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
  const paged = useMemo(() => {
    const start = (page - 1) * pageSize;
    return filtered.slice(start, start + pageSize);
  }, [filtered, page, pageSize]);

  const handleSearch = () => {
    setAppliedFilters(pendingFilters);
    setPage(1);
    setSelectedIds(new Set());
  };

  const handleReset = () => {
    setPendingFilters(EMPTY_FILTERS);
    setAppliedFilters(EMPTY_FILTERS);
    setPage(1);
    setSelectedIds(new Set());
  };

  const handlePageSizeChange = (size: number) => {
    setPageSize(size);
    setPage(1);
  };

  const handleToggleRow = (id: string, checked: boolean) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (checked) next.add(id);
      else next.delete(id);
      return next;
    });
  };

  const handleToggleAll = (checked: boolean) => {
    if (!checked) {
      setSelectedIds(new Set());
      return;
    }
    setSelectedIds(new Set(paged.map((record) => record.id)));
  };

  const handleOpenCreate = () => {
    setCreateForm(EMPTY_CREATE_FORM);
    setView('create');
  };

  const handleSubmitCreate = () => {
    const error = validateCreateForm(createForm);
    if (error) {
      showToast(error);
      return;
    }
    showToast('客户已保存（原型演示）');
    setView('list');
  };

  const appendTagsForCustomer = useCallback((
    customerId: string,
    customerName: string,
    form: RiskTagApplyForm,
    batchCount?: number,
  ) => {
    if (!canManageRiskTags(currentUser)) return '当前角色无打标权限';

    const tag = buildApplyTag(customerId, {
      ...form,
      effectiveFrom: form.effectiveFrom || todayDate(),
    }, currentUser);

    setRiskTagsByCustomer((prev) => {
      const next = {
        ...prev,
        [customerId]: [...(prev[customerId] ?? []), tag],
      };
      refreshRecordLabels(next);
      return next;
    });

    setOperationLogs((prev) => [
      buildApplyLog(tag, customerName, currentUser, batchCount),
      ...prev,
    ]);

    return null;
  }, [currentUser, refreshRecordLabels]);

  const handleApplyTag = useCallback((form: RiskTagApplyForm): string | null => {
    if (!tagDrawerRecord) return '未选择客户';
    if (!canApplyRiskTagByName(currentUser, form.tagName)) return '当前角色无权选择该标签';
    const result = appendTagsForCustomer(tagDrawerRecord.id, tagDrawerRecord.name, form);
    if (!result) {
      showToast(form.riskLevel === '高' || form.riskLevel === '极高'
        ? '已提交审批，待法务/风控确认'
        : '标签已生效');
    }
    return result;
  }, [appendTagsForCustomer, currentUser, showToast, tagDrawerRecord]);

  const handleBatchApply = useCallback((form: RiskTagApplyForm, customerIds: string[]): string | null => {
    if (!canBatchTag(currentUser)) return '当前角色无批量打标权限';

    const newLogs = [...operationLogs];
    const nextTags = { ...riskTagsByCustomer };

    customerIds.forEach((customerId) => {
      const record = records.find((item) => item.id === customerId);
      if (!record) return;

      const tag = buildApplyTag(customerId, {
        ...form,
        effectiveFrom: form.effectiveFrom || todayDate(),
      }, currentUser);

      nextTags[customerId] = [...(nextTags[customerId] ?? []), tag];
      newLogs.unshift(buildApplyLog(tag, record.name, currentUser, customerIds.length));
    });

    setRiskTagsByCustomer(nextTags);
    refreshRecordLabels(nextTags);
    setOperationLogs(newLogs);
    showToast(`已为 ${customerIds.length} 个客户提交打标`);
    setSelectedIds(new Set());
    return null;
  }, [currentUser, operationLogs, records, refreshRecordLabels, riskTagsByCustomer, showToast]);

  const handleRemoveTag = useCallback((tagId: string, reason: string): string | null => {
    if (!tagDrawerRecord) return '未选择客户';
    const tags = riskTagsByCustomer[tagDrawerRecord.id] ?? [];
    const target = tags.find((tag) => tag.id === tagId);
    if (!target) return '标签不存在';
    if (!canRemoveRiskTag(currentUser, target.tagType)) return '当前角色无权移除此类型标签';

    const now = formatNow();
    setRiskTagsByCustomer((prev) => {
      const nextTags = (prev[tagDrawerRecord.id] ?? []).map((tag) =>
        tag.id === tagId ? { ...tag, status: '已移除' as const, updatedAt: now } : tag,
      );
      const next = { ...prev, [tagDrawerRecord.id]: nextTags };
      refreshRecordLabels(next);
      return next;
    });

    setOperationLogs((prev) => [
      buildRemoveLog({ ...target, status: '已移除', updatedAt: now }, tagDrawerRecord.name, currentUser, reason),
      ...prev,
    ]);
    showToast('标签已移除');
    return null;
  }, [currentUser, refreshRecordLabels, riskTagsByCustomer, showToast, tagDrawerRecord]);

  const handleApproveTag = useCallback((tagId: string, approved: boolean, rejectReason?: string): string | null => {
    if (!tagDrawerRecord) return '未选择客户';
    if (!canApproveRiskTag(currentUser)) return '当前角色无审批权限';

    const tags = riskTagsByCustomer[tagDrawerRecord.id] ?? [];
    const target = tags.find((tag) => tag.id === tagId);
    if (!target || target.status !== '待审批') return '标签不可审批';

    const now = formatNow();
    setRiskTagsByCustomer((prev) => {
      const nextTags = (prev[tagDrawerRecord.id] ?? []).map((tag) => {
        if (tag.id !== tagId) return tag;
        return approved
          ? { ...tag, status: '生效中' as const, approver: currentUser.name, approvedAt: now, updatedAt: now }
          : { ...tag, status: '已驳回' as const, approver: currentUser.name, approvedAt: now, rejectReason, updatedAt: now };
      });
      const next = { ...prev, [tagDrawerRecord.id]: nextTags };
      refreshRecordLabels(next);
      return next;
    });

    setOperationLogs((prev) => [
      buildApprovalLog(
        { ...target, status: approved ? '生效中' : '已驳回' },
        tagDrawerRecord.name,
        currentUser,
        approved,
        rejectReason,
      ),
      ...prev,
    ]);
    showToast(approved ? '审批通过，标签已生效' : '已驳回该标签');
    return null;
  }, [currentUser, refreshRecordLabels, riskTagsByCustomer, showToast, tagDrawerRecord]);

  const handleDirectoryRoute = useCallback((node: AnnotationDirectoryRouteNode) => {
    const payload = node.payload as { pageId?: string } | undefined;
    const pageId: CustomerPageId = payload?.pageId === 'create' ? 'create' : 'list';
    if (pageId === 'create') {
      navigationRef.current.openCreate?.();
    } else {
      navigationRef.current.backToList?.();
    }
  }, []);

  const annotationOptions = useMemo<AnnotationViewerOptions>(
    () => ({
      showToolbar: true,
      showThemeToggle: true,
      showColorFilter: true,
      emptyWhenNoData: false,
      toolbarEdge: 'right',
      currentPageId: view,
      onDirectoryRoute: handleDirectoryRoute,
    }),
    [view, handleDirectoryRoute],
  );

  const drawerTags = tagDrawerRecord ? (riskTagsByCustomer[tagDrawerRecord.id] ?? []) : [];

  return (
    <>
      <div className="vm-page cm-page">
        {view === 'create' ? (
          <CreatePage
            form={createForm}
            onChange={(patch) => setCreateForm((prev) => ({ ...prev, ...patch }))}
            onReset={() => setCreateForm(EMPTY_CREATE_FORM)}
            onSubmit={handleSubmitCreate}
            onBack={() => setView('list')}
          />
        ) : (
          <>

            <div className="cm-role-bar" data-annotation-id="cm-risk-role-switch">
              <span className="cm-role-bar-label">当前操作角色（原型演示）：</span>
              <select
                className="vm-input cm-role-select"
                value={currentUser.name}
                onChange={(e) => {
                  const user = MOCK_USERS.find((item) => item.name === e.target.value);
                  if (user) setCurrentUser(user);
                }}
              >
                {MOCK_USERS.map((user) => (
                  <option key={user.name} value={user.name}>
                    {user.name} · {user.department}
                  </option>
                ))}
              </select>
              {!canManageRiskTags(currentUser) && (
                <span className="cm-role-hint">销售角色仅可查看，不可打标</span>
              )}
            </div>

            <FilterPanel
              records={records}
              filters={pendingFilters}
              onChange={(patch) => setPendingFilters((prev) => ({ ...prev, ...patch }))}
              onReset={handleReset}
              onSearch={handleSearch}
            />

            <section className="vm-table-section">
              <div className="vm-table-toolbar" data-annotation-id="cm-list-toolbar">
                <div className="vm-table-actions">
                  <button type="button" className="vm-btn vm-btn-primary ldb-toolbar-btn" onClick={handleOpenCreate} data-vm-icon="plus">新增客户
                  </button>
                  <button
                    type="button"
                    className="vm-btn vm-btn-secondary ldb-toolbar-btn"
                    data-vm-icon="import"
                    onClick={() => showToast('批量导入（原型演示）')}
                  >
                    批量导入
                  </button>
                  {canBatchTag(currentUser) && selectedIds.size > 0 && (
                    <button
                      type="button"
                      className="vm-btn vm-btn-secondary ldb-toolbar-btn"
                      data-vm-icon="plus"
                      onClick={() => setBatchTagOpen(true)}
                      data-annotation-id="cm-batch-risk-tag-btn"
                    >
                      批量打标（{selectedIds.size}）
                    </button>
                  )}
                </div>
                <button
                  type="button"
                  className="vm-btn vm-btn-ghost ldb-toolbar-btn"
                  data-vm-icon="download"
                  onClick={() => showToast(`批量导出（原型演示）：当前列表共 ${filtered.length} 条`)}
                >
                  批量导出
                </button>
              </div>

              <div className="vm-table-card">
                <CustomerTable
                  records={paged}
                  selectedIds={selectedIds}
                  riskTagsByCustomer={riskTagsByCustomer}
                  currentUser={currentUser}
                  onToggleRow={handleToggleRow}
                  onToggleAll={handleToggleAll}
                  onView={(record) => showToast(`详情：${record.name}（原型演示）`)}
                  onEdit={(record) => showToast(`编辑：${record.name}（原型演示）`)}
                  onDelete={(record) => showToast(`删除：${record.name}（原型演示）`)}
                  onManageTags={setTagDrawerRecord}
                />
                <div className="vm-table-footer">
                  <TablePagination
                    page={Math.min(page, totalPages)}
                    pageSize={pageSize}
                    total={filtered.length}
                    onPageChange={setPage}
                    onPageSizeChange={handlePageSizeChange}
                  />
                </div>
              </div>
            </section>
          </>
        )}

        {toast && <div className="vm-toast" role="status" aria-live="polite">{toast}</div>}
      </div>

      <RiskTagDrawer
        open={!!tagDrawerRecord}
        record={tagDrawerRecord}
        tags={drawerTags}
        logs={operationLogs}
        currentUser={currentUser}
        onClose={() => setTagDrawerRecord(null)}
        onApply={handleApplyTag}
        onRemove={handleRemoveTag}
        onApprove={handleApproveTag}
      />

      <BatchRiskTagModal
        open={batchTagOpen}
        records={records}
        selectedIds={selectedIds}
        riskTagsByCustomer={riskTagsByCustomer}
        currentUser={currentUser}
        onClose={() => setBatchTagOpen(false)}
        onSubmit={handleBatchApply}
      />

      <PrototypeAnnotationHost
        source={annotationSourceDocument as AnnotationSourceDocument}
        options={annotationOptions}
      />
    </>
  );
}
