import { useState } from 'react';
import { Card, Table, Button, Space, Tag, Popconfirm, Tooltip, Typography, message } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { PlusOutlined, EditOutlined, DeleteOutlined, ReloadOutlined } from '@ant-design/icons';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import {
  listCustomers, createCustomer, updateCustomer, rotateCustomerToken, deleteCustomer,
  type CustomerListItem, type CreateCustomerPayload, type UpdateCustomerPayload,
} from '../api/customers';
import { CustomerFormModal } from '../components/customers/CustomerFormModal';
import { TokenShownOnceModal } from '../components/customers/TokenShownOnceModal';

const { Text } = Typography;

type FormMode = { kind: 'create' } | { kind: 'edit'; customer: CustomerListItem };

export function AdminCustomersPage() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const [formMode, setFormMode] = useState<FormMode | null>(null);
  const [formError, setFormError] = useState<string | null>(null);
  const [tokenModal, setTokenModal] = useState<{ open: boolean; code: string | null; token: string | null }>({
    open: false, code: null, token: null,
  });

  const { data: customers = [], isLoading } = useQuery({
    queryKey: ['admin', 'customers'],
    queryFn: listCustomers,
  });

  const invalidate = () => qc.invalidateQueries({ queryKey: ['admin', 'customers'] });

  const createMut = useMutation({
    mutationFn: (p: CreateCustomerPayload) => createCustomer(p),
    onSuccess: (result) => {
      setFormMode(null);
      setFormError(null);
      setTokenModal({ open: true, code: result.customer.code, token: result.token });
      invalidate();
    },
    onError: (err: unknown) => setFormError(extractError(err)),
  });

  const updateMut = useMutation({
    mutationFn: ({ id, payload }: { id: string; payload: UpdateCustomerPayload }) => updateCustomer(id, payload),
    onSuccess: () => {
      message.success('Customer updated');
      setFormMode(null);
      setFormError(null);
      invalidate();
    },
    onError: (err: unknown) => setFormError(extractError(err)),
  });

  const rotateMut = useMutation({
    mutationFn: (id: string) => rotateCustomerToken(id),
    onSuccess: (result) => {
      setTokenModal({ open: true, code: result.customer.code, token: result.token });
      invalidate();
    },
    onError: (err: unknown) => message.error(extractError(err)),
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteCustomer(id),
    onSuccess: () => { message.success('Customer deleted'); invalidate(); },
    onError: (err: unknown) => message.error(extractError(err)),
  });

  const handleSubmit = (payload: CreateCustomerPayload | UpdateCustomerPayload) => {
    setFormError(null);
    if (formMode?.kind === 'edit') {
      updateMut.mutate({ id: formMode.customer.id, payload: payload as UpdateCustomerPayload });
    } else {
      createMut.mutate(payload as CreateCustomerPayload);
    }
  };

  const columns: ColumnsType<CustomerListItem> = [
    { title: 'Code', dataIndex: 'code', key: 'code', render: (v) => <Text strong>{v}</Text> },
    { title: 'Name', dataIndex: 'name', key: 'name' },
    {
      title: 'Status',
      dataIndex: 'isActive',
      key: 'isActive',
      render: (v: boolean) => (v ? <Tag color="green">Active</Tag> : <Tag color="red">Disabled</Tag>),
    },
    {
      title: 'Last push',
      dataIndex: 'lastSeenAt',
      key: 'lastSeenAt',
      render: (v: string | null) =>
        v ? new Date(v).toLocaleString() : <Text type="secondary">Never</Text>,
    },
    {
      title: 'Token issued',
      key: 'token',
      render: (_, c) => {
        const ts = c.tokenRotatedAt ?? c.tokenIssuedAt;
        return new Date(ts).toLocaleDateString();
      },
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_, c) => (
        <Space>
          <Button size="small" icon={<EditOutlined />} onClick={() => { setFormError(null); setFormMode({ kind: 'edit', customer: c }); }}>
            Edit
          </Button>
          <Tooltip title="Generate a new token. Old token stops working immediately.">
            <Popconfirm
              title={`Rotate token for ${c.code}?`}
              description="The customer's push service will fail until their .env is updated with the new token."
              okText="Rotate"
              okButtonProps={{ danger: true }}
              onConfirm={() => rotateMut.mutate(c.id)}
            >
              <Button size="small" icon={<ReloadOutlined />} loading={rotateMut.isPending && rotateMut.variables === c.id}>
                Rotate token
              </Button>
            </Popconfirm>
          </Tooltip>
          <Popconfirm
            title={`Delete ${c.code}?`}
            description="All this customer's mirrored data (sites, devices, measurements, events) is removed."
            okText="Delete"
            okButtonProps={{ danger: true }}
            onConfirm={() => deleteMut.mutate(c.id)}
          >
            <Button size="small" danger icon={<DeleteOutlined />}>Delete</Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <Card
      title="Customers"
      extra={
        <Button
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => { setFormError(null); setFormMode({ kind: 'create' }); }}
        >
          Register customer
        </Button>
      }
    >
      <Table<CustomerListItem>
        rowKey="id"
        columns={columns}
        dataSource={customers}
        loading={isLoading}
        pagination={{ pageSize: 25 }}
        onRow={(record) => ({
          onClick: (e) => {
            const t = e.target as HTMLElement;
            if (t.closest('button, .ant-popover')) return;
            navigate(`/admin/customers/${record.id}`);
          },
          style: { cursor: 'pointer' },
        })}
      />

      <CustomerFormModal
        open={formMode !== null}
        mode={formMode}
        submitting={createMut.isPending || updateMut.isPending}
        error={formError}
        onClose={() => { setFormMode(null); setFormError(null); }}
        onSubmit={handleSubmit}
      />

      <TokenShownOnceModal
        open={tokenModal.open}
        customerCode={tokenModal.code}
        token={tokenModal.token}
        onClose={() => setTokenModal({ open: false, code: null, token: null })}
      />
    </Card>
  );
}

function extractError(err: unknown): string {
  if (typeof err === 'object' && err !== null && 'response' in err) {
    const data = (err as { response?: { data?: { error?: string } } }).response?.data;
    if (data?.error) return data.error;
  }
  return 'Request failed.';
}
