import React, { useEffect, useMemo, useState } from 'react';
import { AlertTriangle, Clock, Plus, ShieldAlert, Tag, X } from 'lucide-react';
import type { CustomerRecord } from '../types';
import type {
  CustomerRiskTag,
  MockUser,
  RiskTagApplyForm,
  RiskTagOperationLog,
  TagCategoryCode,
} from '../types/riskTag';
import {
  canAddRiskTags,
  canApproveRiskTag,
  canMaintainCategory,
  canRemoveRiskTag,
  canViewFinanceSensitive,
  roleLabel,
  roleToTagCategory,
} from '../utils/permissions';
import { TAG_CATEGORY_META, TAG_CATEGORY_ORDER } from '../utils/riskTagConstants';
import { EMPTY_RISK_TAG_FORM } from '../types/riskTag';
import {
  defaultExpireDate,
  defaultNextReviewDate,
  getDisplayStatusName,
  getTaggedAt,
  groupTagsByCategory,
  hasDuplicateActiveTag,
  isHighRiskLevel,
  isLegalRiskTag,
  legalTagsNeedReview,
  normalizeRiskTag,
  todayDate,
  validateApplyForm,
} from '../utils/riskTagStore';
import { RiskTagApplyFormSection, RiskTagDetailCard } from './RiskTagForm';

type DrawerTab = 'tags' | 'add' | 'logs';

interface RiskTagDrawerProps {
  open: boolean;
  record: CustomerRecord | null;
  tags: CustomerRiskTag[];
  logs: RiskTagOperationLog[];
  currentUser: MockUser;
  onClose: () => void;
  onApply: (form: RiskTagApplyForm) => string | null;
  onRemove: (tagId: string, reason: string, isApplication?: boolean) => string | null;
  onApprove: (tagId: string, approved: boolean, rejectReason?: string) => string | null;
  onDispatchLegalTodos?: (customerId: string, customerName: string, overdueTags: CustomerRiskTag[]) => void;
}

function actionTagClass(action: RiskTagOperationLog['action']): string {
  switch (action) {
    case '新增标签': return 'cm-log-tag--add';
    case '解除标签': return 'cm-log-tag--remove';
    case '提交审批': return 'cm-log-tag--pending';
    case '审批通过': return 'cm-log-tag--pass';
    case '审批驳回': return 'cm-log-tag--reject';
    case '到期复核': return 'cm-log-tag--review';
    case '工作台待办': return 'cm-log-tag--review';
    default: return '';
  }
}

function levelClass(level: CustomerRiskTag['riskLevel']): string {
  switch (level) {
    case 'low': return 'cm-risk-tag--low';
    case 'medium': return 'cm-risk-tag--medium';
    case 'high': return 'cm-risk-tag--high';
    case 'fatal': return 'cm-risk-tag--critical';
    default: return 'cm-risk-tag--medium';
  }
}

interface CategorySectionProps {
  category: TagCategoryCode;
  tags: CustomerRiskTag[];
  currentUser: MockUser;
  onDetail: (id: string) => void;
  onRemove: (id: string) => void;
  onApprove: (id: string) => void;
  onAddInCategory: () => void;
}

function renderTagTimeFields(tag: CustomerRiskTag) {
  const normalized = normalizeRiskTag(tag);
  if (isLegalRiskTag(normalized)) {
    return (
      <>
        <div><dt>打标时间</dt><dd>{getTaggedAt(normalized)}</dd></div>
        <div><dt>复核周期</dt><dd>{normalized.reviewCycle}</dd></div>
        <div><dt>下次复核时间</dt><dd>{normalized.nextReviewAt || '—'}</dd></div>
        <div><dt>最后复核时间</dt><dd>{normalized.lastReviewedAt || '—'}</dd></div>
      </>
    );
  }
  return (
    <>
      <div><dt>打标时间</dt><dd>{getTaggedAt(normalized)}</dd></div>
      <div><dt>有效期至</dt><dd>{normalized.expireDate}</dd></div>
    </>
  );
}

function CategorySection({
  category,
  tags,
  currentUser,
  onDetail,
  onRemove,
  onApprove,
  onAddInCategory,
}: CategorySectionProps) {
  const meta = TAG_CATEGORY_META[category];
  const canMaintain = canMaintainCategory(currentUser, category);
  const visibleTags = tags.filter((t) => t.status !== 'removed' && t.status !== 'rejected');
  const zoneAnnotationId = category === 'legal' ? 'cm-risk-zone-legal' : undefined;

  return (
    <section className="cm-risk-zone" data-category={category} data-annotation-id={zoneAnnotationId}>
      <header className="cm-risk-zone-head">
        <div>
          <h3>{meta.name}标签</h3>
          <p className="cm-muted">{meta.description}</p>
        </div>
        {canMaintain ? (
          <span className="cm-risk-zone-perm cm-risk-zone-perm--ok">可维护</span>
        ) : (
          <span className="cm-risk-zone-perm cm-risk-zone-perm--readonly">当前角色无权维护该类标签</span>
        )}
      </header>

      {canMaintain && (
        <button type="button" className="vm-btn vm-btn-secondary cm-risk-zone-add" onClick={onAddInCategory}>
          <Plus size={14} aria-hidden /> 新增该类标签
        </button>
      )}

      {visibleTags.length === 0 ? (
        <p className="cm-risk-zone-empty">暂无该类风险标签</p>
      ) : (
        <div className="cm-risk-zone-cards">
          {visibleTags.map((tag) => {
            const normalized = normalizeRiskTag(tag);
            const displayStatus = getDisplayStatusName(normalized);
            const dueSoon = isLegalRiskTag(normalized) && normalized.reviewStatus === 'dueSoon';
            const overdue = isLegalRiskTag(normalized) && normalized.reviewStatus === 'overdue';
            const canRemove = canRemoveRiskTag(currentUser, normalized.tagCategory)
              && normalized.status === 'active'
              && !normalized.removalRequested;
            const showApprove = canApproveRiskTag(currentUser)
              && (normalized.status === 'pending' || (normalized.status === 'active' && normalized.removalRequested));

            return (
              <article key={normalized.id} className="cm-risk-tag-item">
                <div className="cm-risk-tag-item-head">
                  <div>
                    <strong>{normalized.tagName}</strong>
                    <span className={`cm-risk-tag-badge ${levelClass(normalized.riskLevel)}`}>
                      {normalized.riskLevelName}
                    </span>
                    {dueSoon && <span className="cm-risk-badge cm-risk-badge--warn">即将复核</span>}
                    {overdue && <span className="cm-risk-badge cm-risk-badge--review">待复核</span>}
                  </div>
                  <span className={`cm-risk-status cm-risk-status--${normalized.status}`}>{displayStatus}</span>
                </div>
                <dl className="cm-risk-tag-fields">
                  {renderTagTimeFields(normalized)}
                  <div><dt>责任部门</dt><dd>{normalized.responsibleDept}</dd></div>
                  <div><dt>操作人</dt><dd>{normalized.createdBy}</dd></div>
                </dl>
                <p className="cm-risk-tag-reason">{normalized.reason}</p>
                <div className="cm-risk-tag-item-actions">
                  <button type="button" className="vm-btn vm-btn-link" onClick={() => onDetail(normalized.id)}>
                    查看详情
                  </button>
                  {showApprove && (
                    <button type="button" className="vm-btn vm-btn-link" onClick={() => onApprove(normalized.id)}>
                      审批
                    </button>
                  )}
                  {canRemove && (
                    <button
                      type="button"
                      className="vm-btn vm-btn-link cm-link-danger"
                      onClick={() => onRemove(normalized.id)}
                    >
                      申请解除
                    </button>
                  )}
                </div>
              </article>
            );
          })}
        </div>
      )}
    </section>
  );
}

export function RiskTagDrawer({
  open,
  record,
  tags,
  logs,
  currentUser,
  onClose,
  onApply,
  onRemove,
  onApprove,
  onDispatchLegalTodos,
}: RiskTagDrawerProps) {
  const [tab, setTab] = useState<DrawerTab>('tags');
  const [detailId, setDetailId] = useState<string | null>(null);
  const [form, setForm] = useState<RiskTagApplyForm>(EMPTY_RISK_TAG_FORM);
  const [removeReason, setRemoveReason] = useState('');
  const [removeTargetId, setRemoveTargetId] = useState<string | null>(null);
  const [rejectReason, setRejectReason] = useState('');
  const [approveTargetId, setApproveTargetId] = useState<string | null>(null);
  const [confirmHighRisk, setConfirmHighRisk] = useState(false);
  const [error, setError] = useState('');

  const detailTag = useMemo(
    () => tags.find((tag) => tag.id === detailId) ?? null,
    [tags, detailId],
  );

  const customerLogs = useMemo(
    () => logs
      .filter((log) => log.customerId === record?.id)
      .sort((a, b) => b.createdAt.localeCompare(a.createdAt)),
    [logs, record?.id],
  );

  const groupedTags = useMemo(() => groupTagsByCategory(tags), [tags]);
  const legalOverdueTags = useMemo(() => legalTagsNeedReview(tags), [tags]);

  const disabledTagNames = useMemo(
    () => tags
      .filter((tag) => tag.status === 'active' || tag.status === 'pending')
      .map((tag) => tag.tagName),
    [tags],
  );

  const removeTarget = useMemo(
    () => tags.find((t) => t.id === removeTargetId) ?? null,
    [tags, removeTargetId],
  );

  const approveTarget = useMemo(
    () => tags.find((t) => t.id === approveTargetId) ?? null,
    [tags, approveTargetId],
  );

  useEffect(() => {
    if (!open) return;
    const category = roleToTagCategory(currentUser);
    const taggedAt = todayDate();
    setForm({
      ...EMPTY_RISK_TAG_FORM,
      tagCategory: category,
      taggedAt,
      effectiveDate: taggedAt,
      expireDate: category === 'legal' ? '' : defaultExpireDate(category, taggedAt),
      nextReviewAt: category === 'legal'
        ? defaultNextReviewDate(category, '3个月', taggedAt)
        : '',
      reviewCycle: '3个月',
    });
    setConfirmHighRisk(false);
    setError('');
  }, [currentUser, open]);

  useEffect(() => {
    if (!open || !record || legalOverdueTags.length === 0 || !onDispatchLegalTodos) return;
    onDispatchLegalTodos(record.id, record.name, legalOverdueTags);
  }, [open, record, legalOverdueTags, onDispatchLegalTodos]);

  const resetAddForm = (category?: TagCategoryCode) => {
    const cat = category ?? roleToTagCategory(currentUser);
    const taggedAt = todayDate();
    setForm({
      ...EMPTY_RISK_TAG_FORM,
      tagCategory: cat,
      taggedAt,
      effectiveDate: taggedAt,
      expireDate: cat === 'legal' ? '' : defaultExpireDate(cat, taggedAt),
      nextReviewAt: cat === 'legal'
        ? defaultNextReviewDate(cat, '3个月', taggedAt)
        : '',
      reviewCycle: '3个月',
    });
    setError('');
    setConfirmHighRisk(false);
  };

  if (!open || !record) return null;

  const handleSubmitApply = () => {
    const validation = validateApplyForm(form);
    if (validation) {
      setError(validation);
      return;
    }
    if (hasDuplicateActiveTag(tags, form.tagName)) {
      setError('该客户已存在同名有效标签');
      return;
    }
    if (isHighRiskLevel(form.riskLevel) && !confirmHighRisk) {
      setConfirmHighRisk(true);
      return;
    }
    const result = onApply(form);
    if (result) {
      setError(result);
      return;
    }
    resetAddForm();
    setTab('tags');
  };

  const handleConfirmRemove = () => {
    if (!removeTargetId || !removeTarget) return;
    if (removeReason.trim().length < 5) {
      setError('解除原因至少 5 个字');
      return;
    }
    const result = onRemove(removeTargetId, removeReason.trim(), true);
    if (result) {
      setError(result);
      return;
    }
    setRemoveTargetId(null);
    setRemoveReason('');
    setError('');
  };

  const handleConfirmApprove = (approved: boolean) => {
    if (!approveTargetId) return;
    if (!approved && !rejectReason.trim()) {
      setError('请填写驳回原因');
      return;
    }
    const result = onApprove(approveTargetId, approved, rejectReason.trim() || undefined);
    if (result) {
      setError(result);
      return;
    }
    setApproveTargetId(null);
    setRejectReason('');
    setError('');
  };

  const openAddForCategory = (category: TagCategoryCode) => {
    resetAddForm(category);
    setTab('add');
  };

  return (
    <div className="cm-drawer-backdrop" role="presentation" onClick={onClose}>
      <aside
        className="cm-drawer cm-drawer--wide"
        role="dialog"
        aria-modal="true"
        aria-labelledby="cm-risk-drawer-title"
        data-annotation-id="cm-risk-tag-drawer"
        onClick={(e) => e.stopPropagation()}
      >
        <header className="cm-drawer-header">
          <div>
            <h2 id="cm-risk-drawer-title">风险标签</h2>
            <p>{record.name}（{record.code}）</p>
          </div>
          <button type="button" className="vm-modal-close" onClick={onClose} aria-label="关闭">
            <X size={18} aria-hidden />
          </button>
        </header>

        <nav className="cm-drawer-tabs" aria-label="标签管理分区">
          <button type="button" className={tab === 'tags' ? 'is-active' : ''} onClick={() => setTab('tags')}>
            <Tag size={14} aria-hidden /> 当前标签
          </button>
          <button
            type="button"
            className={tab === 'add' ? 'is-active' : ''}
            onClick={() => { setTab('add'); resetAddForm(); }}
            disabled={!canAddRiskTags(currentUser)}
          >
            <Plus size={14} aria-hidden /> 新增标签
          </button>
          <button type="button" className={tab === 'logs' ? 'is-active' : ''} onClick={() => setTab('logs')}>
            <Clock size={14} aria-hidden /> 操作日志
          </button>
        </nav>

        <div className="cm-drawer-body">
          {error && <div className="cm-risk-error" role="alert">{error}</div>}

          {tab === 'tags' && (
            <div className="cm-risk-zones">
              {legalOverdueTags.length > 0 && (
                <div
                  className="cm-risk-review-banner cm-risk-review-banner--legal"
                  role="status"
                  data-annotation-id="cm-legal-workbench-todo-banner"
                >
                  <AlertTriangle size={16} aria-hidden />
                  存在待复核法务风险标签，已向法务工作台发起待办，请前往查验；确认可解除后在本页「申请解除」。
                </div>
              )}
              {TAG_CATEGORY_ORDER.map((category) => (
                <CategorySection
                  key={category}
                  category={category}
                  tags={groupedTags[category]}
                  currentUser={currentUser}
                  onDetail={setDetailId}
                  onRemove={(id) => { setRemoveTargetId(id); setRemoveReason(''); setError(''); }}
                  onApprove={(id) => { setApproveTargetId(id); setRejectReason(''); setError(''); }}
                  onAddInCategory={() => openAddForCategory(category)}
                />
              ))}
            </div>
          )}

          {tab === 'add' && (
            <RiskTagApplyFormSection
              form={form}
              currentUser={currentUser}
              onChange={(patch) => {
                setConfirmHighRisk(false);
                setForm((prev) => ({ ...prev, ...patch }));
              }}
              disabledTagNames={disabledTagNames}
            />
          )}

          {tab === 'logs' && (
            <ol className="cm-risk-log-list">
              {customerLogs.length === 0 && <li className="cm-muted">暂无操作日志</li>}
              {customerLogs.map((log) => {
                const isFinanceSensitive = log.tagCategory === 'finance'
                  && !canViewFinanceSensitive(currentUser);
                const reasonText = isFinanceSensitive
                  ? '财务敏感信息已隐藏'
                  : log.reason || log.detail || '—';

                return (
                  <li key={log.id}>
                    <div className="cm-risk-log-head">
                      <span className={`cm-log-tag ${actionTagClass(log.action)}`}>{log.action}</span>
                      <time>{log.createdAt}</time>
                    </div>
                    <p className="cm-risk-log-title">
                      {log.tagName}
                      <span className="cm-muted"> · {log.tagCategoryName}</span>
                    </p>
                    <p>{reasonText}</p>
                    <div className="cm-risk-log-meta">
                      <span>{log.operator}</span>
                      <span className="cm-muted">（{roleLabel(log.operatorRole)}）</span>
                      {(log.statusBefore || log.statusAfter) && (
                        <span className="cm-muted">
                          {log.statusBefore} → {log.statusAfter}
                        </span>
                      )}
                    </div>
                  </li>
                );
              })}
            </ol>
          )}
        </div>

        <footer className="cm-drawer-footer">
          {tab === 'add' && canAddRiskTags(currentUser) ? (
            <>
              <button type="button" className="vm-btn vm-btn-ghost" onClick={() => { setTab('tags'); resetAddForm(); }}>
                取消
              </button>
              {confirmHighRisk ? (
                <button type="button" className="vm-btn vm-btn-primary" onClick={handleSubmitApply}>
                  <ShieldAlert size={14} aria-hidden /> 确认提交高风险标签
                </button>
              ) : (
                <button type="button" className="vm-btn vm-btn-primary" onClick={handleSubmitApply}>
                  提交打标
                </button>
              )}
            </>
          ) : (
            <button type="button" className="vm-btn vm-btn-ghost" onClick={onClose}>关闭</button>
          )}
        </footer>

        {detailTag && (
          <div className="cm-drawer-subpanel">
            <RiskTagDetailCard tag={detailTag} currentUser={currentUser} onClose={() => setDetailId(null)} />
          </div>
        )}

        {removeTargetId && removeTarget && (
          <div className="cm-drawer-overlay-panel" data-annotation-id="cm-risk-removal-apply">
            <h3>申请解除标签</h3>
            <p className="cm-modal-hint">
              {isLegalRiskTag(normalizeRiskTag(removeTarget))
                ? '法务查验完成后，如需解除标签请在此提交申请，经审批后生效。'
                : '移除风险标签需提交解除申请，经审批后生效。'}
            </p>
            <textarea
              className="vm-input cm-textarea"
              rows={3}
              value={removeReason}
              placeholder="请填写解除原因（至少 5 字）"
              onChange={(e) => setRemoveReason(e.target.value)}
            />
            <div className="cm-drawer-overlay-actions">
              <button type="button" className="vm-btn vm-btn-ghost" onClick={() => setRemoveTargetId(null)}>取消</button>
              <button type="button" className="vm-btn vm-btn-primary cm-link-danger-btn" onClick={handleConfirmRemove}>
                确认提交
              </button>
            </div>
          </div>
        )}

        {approveTargetId && approveTarget && (
          <div className="cm-drawer-overlay-panel" data-annotation-id="cm-risk-removal-approval">
            <h3>{approveTarget.removalRequested ? '审批解除申请' : '审批标签'}</h3>
            <p className="cm-modal-hint">
              {approveTarget.removalRequested
                ? '解除申请需法务/风控/管理层确认；通过后标签解除，驳回则保持生效。'
                : '高风险标签需法务/风控/管理层确认后方可生效。'}
            </p>
            <textarea
              className="vm-input cm-textarea"
              rows={2}
              value={rejectReason}
              placeholder="若驳回，请填写原因"
              onChange={(e) => setRejectReason(e.target.value)}
            />
            <div className="cm-drawer-overlay-actions">
              <button type="button" className="vm-btn vm-btn-ghost" onClick={() => setApproveTargetId(null)}>取消</button>
              <button type="button" className="vm-btn vm-btn-ghost" onClick={() => handleConfirmApprove(false)}>驳回</button>
              <button type="button" className="vm-btn vm-btn-primary" onClick={() => handleConfirmApprove(true)}>通过</button>
            </div>
          </div>
        )}
      </aside>
    </div>
  );
}
