import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { FormEvent, useDeferredValue, useEffect, useMemo, useState } from 'react';
import { api } from '../../api/client';
import type { AdminUser, CustomerUserInput } from '../../api/types';

const customerMenus = [
  { key: 'monitor', label: '全局监控', description: '查看授权车辆的实时位置与状态' },
  { key: 'vehicles', label: '车辆查询', description: '查看车辆档案与最新遥测' },
  { key: 'tracks', label: '轨迹回放', description: '查询授权车辆的历史轨迹' },
  { key: 'statistics', label: '里程查询', description: '查询授权车辆的每日与区间里程' }
];

type Draft = {
  username: string;
  displayName: string;
  password: string;
  status: 'enabled' | 'disabled';
  customerRef: string;
  tenantRef: string;
  menuKeys: string[];
  vehicleVins: string[];
};

const emptyDraft: Draft = { username: '', displayName: '', password: '', status: 'enabled', customerRef: '', tenantRef: '', menuKeys: ['monitor', 'vehicles', 'tracks', 'statistics'], vehicleVins: [] };

function draftFromUser(user?: AdminUser): Draft {
  if (!user) return { ...emptyDraft, menuKeys: [...emptyDraft.menuKeys], vehicleVins: [] };
  return { username: user.username, displayName: user.displayName, password: '', status: user.status, customerRef: user.customerRef, tenantRef: user.tenantRef, menuKeys: [...user.menuKeys], vehicleVins: [...user.vehicleVins] };
}

function formatTime(value?: string) {
  if (!value) return '尚未登录';
  return new Date(value).toLocaleString('zh-CN', { hour12: false });
}

function uniqueVehicles<T extends { vin: string; plate: string }>(vehicles: T[]) {
  const byVIN = new Map<string, T>();
  for (const vehicle of vehicles) {
    const vin = vehicle.vin.trim().toUpperCase();
    const current = byVIN.get(vin);
    if (!vin || (current?.plate && !vehicle.plate)) continue;
    byVIN.set(vin, vehicle);
  }
  return [...byVIN.values()];
}

export default function UsersPage() {
  const queryClient = useQueryClient();
  const users = useQuery({ queryKey: ['admin-users'], queryFn: ({ signal }) => api.adminUsers(signal), staleTime: 10_000 });
  const customers = useMemo(() => (users.data ?? []).filter((user) => user.userType === 'customer'), [users.data]);
  const [selectedID, setSelectedID] = useState<number | null>(null);
  const [creating, setCreating] = useState(false);
  const selected = useMemo(() => customers.find((user) => user.id === selectedID), [customers, selectedID]);
  const [draft, setDraft] = useState<Draft>(() => draftFromUser());
  const [vehicleKeyword, setVehicleKeyword] = useState('');
  const deferredVehicleKeyword = useDeferredValue(vehicleKeyword.trim());
  const [bulkVINs, setBulkVINs] = useState('');
  const [vehicleLabels, setVehicleLabels] = useState<Record<string, string>>({});
  const [feedback, setFeedback] = useState('');

  useEffect(() => {
    if (!creating && selected) {
      setDraft(draftFromUser(selected));
      setVehicleLabels(Object.fromEntries(selected.vehicles.map((vehicle) => [vehicle.vin, vehicle.plate])));
    }
  }, [creating, selected]);

  const candidates = useQuery({
    queryKey: ['permission-vehicle-candidates', deferredVehicleKeyword],
    queryFn: ({ signal }) => api.vehicleCoverage(new URLSearchParams({ keyword: deferredVehicleKeyword, limit: '20', offset: '0' }), signal),
    enabled: deferredVehicleKeyword.length >= 1,
    staleTime: 30_000
  });
  const assigned = useMemo(() => new Set(draft.vehicleVins), [draft.vehicleVins]);
  const candidateVehicles = useMemo(() => uniqueVehicles(candidates.data?.items ?? []), [candidates.data?.items]);
  useEffect(() => {
    if (candidateVehicles.length === 0) return;
    setVehicleLabels((current) => {
      const next = { ...current };
      for (const vehicle of candidateVehicles) next[vehicle.vin] = vehicle.plate;
      return next;
    });
  }, [candidateVehicles]);

  const save = useMutation({
    mutationFn: async () => {
      const input: CustomerUserInput = { displayName: draft.displayName.trim(), password: draft.password || undefined, status: draft.status, customerRef: draft.customerRef.trim(), tenantRef: draft.tenantRef.trim(), menuKeys: draft.menuKeys, vehicleVins: draft.vehicleVins };
      if (creating) return api.createCustomerUser({ ...input, username: draft.username.trim(), password: draft.password });
      if (!selected) throw new Error('请先选择客户账号');
      return api.updateCustomerUser(selected.id, input);
    },
    onSuccess: async (result) => {
      setFeedback(creating ? '客户账号已创建' : '账号与权限已更新');
      setCreating(false);
      setSelectedID(result.id);
      setDraft((value) => ({ ...value, password: '' }));
      await queryClient.invalidateQueries({ queryKey: ['admin-users'] });
    },
    onError: (error) => setFeedback(error instanceof Error ? error.message : '保存失败')
  });

  const startCreate = () => {
    setCreating(true);
    setSelectedID(null);
    setDraft(draftFromUser());
    setVehicleKeyword('');
    setBulkVINs('');
    setVehicleLabels({});
    setFeedback('');
  };
  const selectCustomer = (user: AdminUser) => {
    setCreating(false);
    setSelectedID(user.id);
    setDraft(draftFromUser(user));
    setVehicleKeyword('');
    setBulkVINs('');
    setFeedback('');
  };
  const toggleVIN = (vin: string) => setDraft((value) => ({ ...value, vehicleVins: value.vehicleVins.includes(vin) ? value.vehicleVins.filter((item) => item !== vin) : [...value.vehicleVins, vin].sort() }));
  const addBulkVINs = () => {
    const next = bulkVINs.split(/[\s,，;；]+/).map((value) => value.trim().toUpperCase()).filter(Boolean);
    setDraft((value) => ({ ...value, vehicleVins: [...new Set([...value.vehicleVins, ...next])].sort() }));
    setBulkVINs('');
  };
  const submit = (event: FormEvent) => { event.preventDefault(); setFeedback(''); save.mutate(); };

  return <div className="v2-user-admin">
    <header className="v2-user-admin-heading">
      <div><h2>客户账号与数据权限</h2><p>账号只会看到已分配的菜单和车辆；权限修改最多在 30 秒内对现有会话生效。</p></div>
      <button type="button" onClick={startCreate}>新建客户账号</button>
    </header>
    <div className="v2-user-admin-grid">
      <aside className="v2-user-list">
        <div className="v2-user-list-summary"><strong>{customers.length}</strong><span>个客户账号</span></div>
        {users.isPending ? <p className="v2-user-empty">正在加载账号…</p> : customers.length === 0 ? <p className="v2-user-empty">还没有客户账号</p> : customers.map((user) => <button key={user.id} type="button" className={selectedID === user.id && !creating ? 'is-active' : ''} onClick={() => selectCustomer(user)}>
          <span className="v2-user-avatar">{user.displayName.slice(0, 1)}</span>
          <span><b>{user.displayName}</b><small>@{user.username} · {user.vehicleVins.length} 辆车</small></span>
          <i className={user.status === 'enabled' ? 'is-enabled' : ''}>{user.status === 'enabled' ? '启用' : '停用'}</i>
        </button>)}
      </aside>
      <main className="v2-user-editor">
        {!creating && !selected ? <div className="v2-user-editor-empty"><strong>选择一个客户账号</strong><p>查看或调整账号状态、菜单和车辆范围。</p><button type="button" onClick={startCreate}>创建第一个客户账号</button></div> : <form onSubmit={submit}>
          <div className="v2-user-editor-title"><div><h3>{creating ? '创建客户账号' : selected?.displayName}</h3><p>{creating ? '设置登录身份和最小必要权限' : `最近登录：${formatTime(selected?.lastLoginAt)}`}</p></div><label className="v2-user-status"><input type="checkbox" checked={draft.status === 'enabled'} onChange={(event) => setDraft((value) => ({ ...value, status: event.target.checked ? 'enabled' : 'disabled' }))} /><span>{draft.status === 'enabled' ? '账号启用' : '账号停用'}</span></label></div>
          <section><h4>登录身份</h4><div className="v2-user-fields">
            <label><span>用户名</span><input required disabled={!creating} value={draft.username} onChange={(event) => setDraft((value) => ({ ...value, username: event.target.value }))} placeholder="例如 customer-huadong" /></label>
            <label><span>客户名称</span><input required value={draft.displayName} onChange={(event) => setDraft((value) => ({ ...value, displayName: event.target.value }))} placeholder="显示在平台右上角" /></label>
            <label><span>{creating ? '初始密码' : '重置密码（可选）'}</span><input required={creating} type="password" autoComplete="new-password" value={draft.password} onChange={(event) => setDraft((value) => ({ ...value, password: event.target.value }))} placeholder="至少 10 位，包含三类字符" /></label>
            <label><span>客户标识（可选）</span><input value={draft.customerRef} onChange={(event) => setDraft((value) => ({ ...value, customerRef: event.target.value }))} placeholder="为 OneOS / RuoYi 映射预留" /></label>
          </div></section>
          <section><h4>菜单权限 <small>只能分配客户开放菜单</small></h4><div className="v2-menu-permissions">{customerMenus.map((menu) => <label key={menu.key} className={draft.menuKeys.includes(menu.key) ? 'is-selected' : ''}><input type="checkbox" checked={draft.menuKeys.includes(menu.key)} onChange={() => setDraft((value) => ({ ...value, menuKeys: value.menuKeys.includes(menu.key) ? value.menuKeys.filter((item) => item !== menu.key) : [...value.menuKeys, menu.key] }))} /><span><b>{menu.label}</b><small>{menu.description}</small></span></label>)}</div></section>
          <section><div className="v2-vehicle-permission-heading"><h4>车辆权限 <small>已选择 {draft.vehicleVins.length} 辆</small></h4>{draft.vehicleVins.length ? <button type="button" onClick={() => setDraft((value) => ({ ...value, vehicleVins: [] }))}>清空</button> : null}</div>
            <div className="v2-vehicle-permission-tools"><label><span>按车牌或 VIN 搜索</span><input value={vehicleKeyword} onChange={(event) => setVehicleKeyword(event.target.value)} placeholder="输入后显示候选车辆" /></label><label><span>批量粘贴 VIN</span><span className="v2-bulk-vin"><input value={bulkVINs} onChange={(event) => setBulkVINs(event.target.value)} placeholder="空格、逗号或换行分隔" /><button type="button" disabled={!bulkVINs.trim()} onClick={addBulkVINs}>加入</button></span></label></div>
            {deferredVehicleKeyword ? <div className="v2-vehicle-candidates">{candidates.isPending ? <p>正在搜索车辆…</p> : candidateVehicles.length === 0 ? <p>没有匹配车辆</p> : candidateVehicles.map((vehicle) => <button type="button" className={assigned.has(vehicle.vin) ? 'is-selected' : ''} key={vehicle.vin} onClick={() => toggleVIN(vehicle.vin)}><span><b>{vehicle.plate || '未登记车牌'}</b><small>{vehicle.vin}</small></span><i>{assigned.has(vehicle.vin) ? '已分配' : '选择'}</i></button>)}</div> : null}
            {draft.vehicleVins.length ? <div className="v2-assigned-vins">{draft.vehicleVins.map((vin) => { const plate = vehicleLabels[vin]; return <button type="button" key={vin} aria-label={`移除 ${plate || vin}`} onClick={() => toggleVIN(vin)}><span><b>{plate || '未登记车牌'}</b><small>{vin}</small></span><i>×</i></button>; })}</div> : <p className="v2-user-empty">尚未分配车辆，客户将无法看到任何车辆数据。</p>}
          </section>
          {feedback ? <p className={`v2-user-feedback${save.isError ? ' is-error' : ''}`} role="status">{feedback}</p> : null}
          <footer><button type="submit" disabled={save.isPending}>{save.isPending ? '正在保存…' : creating ? '创建账号' : '保存权限'}</button></footer>
        </form>}
      </main>
    </div>
  </div>;
}
