import { useState, useEffect, useCallback, useMemo } from 'react';
import { Table, Button, Modal, Drawer, Form, Input, Select, Space, Tag, App, Typography, Switch, Tooltip } from 'antd';
import { PlusOutlined, EditOutlined, CopyOutlined, DeleteOutlined, StarFilled, StarOutlined } from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { api } from '@/lib/api';
import type { SmsMessageTemplate, SmsPaginatedResponse } from '@/types/sms';
import type { AppOutletContext } from '@/types/api';
import { useMobile } from '@/hooks/useMobile';
import { useOutletContext } from 'react-router-dom';
import { useDebounce } from '@/hooks/useDebounce';

const { TextArea } = Input;
const { Text } = Typography;

const CATEGORY_COLORS: Record<string, string> = {
  notification: 'blue',
  campaign: 'purple',
  custom: 'green',
};

/** Known placeholder sample values for live preview */
const SAMPLE_VALUES: Record<string, string> = {
  name: 'Jane Doe',
  phone: '+1 555 000 0000',
  shiftTitle: 'Ward 6 Canvass',
  shiftTime: '2:00 PM',
  shiftDate: 'Mar 15',
  shiftLocation: 'Community Centre',
  organizationName: 'Changemaker',
};

/** Extract {var} names from a template string */
function extractVars(template: string): string[] {
  const vars: string[] = [];
  const regex = /\{(\w+)\}/g;
  let m;
  while ((m = regex.exec(template)) !== null) {
    const v = m[1] as string;
    if (!vars.includes(v)) vars.push(v);
  }
  return vars;
}

/** Calculate SMS segment count */
function segmentCount(length: number): number {
  if (length === 0) return 0;
  if (length <= 160) return 1;
  return Math.ceil(length / 153);
}

/** Render a live preview with sample substitutions */
function renderPreview(template: string): string {
  return template.replace(/\{(\w+)\}/g, (match, key) => SAMPLE_VALUES[key] ?? match);
}

export default function SmsTemplatesPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { message } = App.useApp();
  const { isMobile } = useMobile();

  const [templates, setTemplates] = useState<SmsMessageTemplate[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(true);

  // Filters
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 300);
  const [categoryFilter, setCategoryFilter] = useState<string | undefined>();
  const [favoritesOnly, setFavoritesOnly] = useState(false);

  // Drawer
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);

  // Live template text for character counter + variable extraction
  const [liveTemplate, setLiveTemplate] = useState('');

  useEffect(() => {
    setPageHeader({ title: 'SMS Templates', subtitle: 'Manage reusable SMS message templates' });
  }, [setPageHeader]);

  const fetchTemplates = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string | number> = { page, limit: 50 };
      if (debouncedSearch) params.search = debouncedSearch;
      if (categoryFilter) params.category = categoryFilter;
      if (favoritesOnly) params.isFavorite = 'true';
      const { data } = await api.get<SmsPaginatedResponse<SmsMessageTemplate>>('/sms/templates', { params });
      setTemplates(data.items);
      setTotal(data.total);
    } finally {
      setLoading(false);
    }
  }, [page, debouncedSearch, categoryFilter, favoritesOnly]);

  useEffect(() => { fetchTemplates(); }, [fetchTemplates]);

  // Reset to page 1 when filters change
  useEffect(() => { setPage(1); }, [debouncedSearch, categoryFilter, favoritesOnly]);

  const closeDrawer = () => { setDrawerOpen(false); setLiveTemplate(''); };

  const openCreate = () => {
    setEditingId(null);
    form.resetFields();
    setLiveTemplate('');
    setDrawerOpen(true);
  };

  const openEdit = (record: SmsMessageTemplate) => {
    setEditingId(record.id);
    form.setFieldsValue({
      name: record.name,
      template: record.template,
      description: record.description || '',
      category: record.category || undefined,
    });
    setLiveTemplate(record.template);
    setDrawerOpen(true);
  };

  const openDuplicate = (record: SmsMessageTemplate) => {
    setEditingId(null);
    form.setFieldsValue({
      name: `${record.name} (copy)`,
      template: record.template,
      description: record.description || '',
      category: record.category || undefined,
    });
    setLiveTemplate(record.template);
    setDrawerOpen(true);
  };

  const handleSave = async (values: { name: string; template: string; description?: string; category?: string }) => {
    setSaving(true);
    try {
      if (editingId) {
        await api.put(`/sms/templates/${editingId}`, values);
        message.success('Template updated');
      } else {
        await api.post('/sms/templates', values);
        message.success('Template created');
      }
      closeDrawer();
      form.resetFields();
      fetchTemplates();
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Save failed';
      message.error(msg);
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/sms/templates/${id}`);
      message.success('Template deleted');
      fetchTemplates();
    } catch {
      message.error('Delete failed — system templates cannot be deleted');
    }
  };

  const handleToggleFavorite = async (id: string) => {
    try {
      await api.post(`/sms/templates/${id}/favorite`);
      fetchTemplates();
    } catch {
      message.error('Failed to toggle favorite');
    }
  };

  // Computed values for drawer
  const liveVars = useMemo(() => extractVars(liveTemplate), [liveTemplate]);
  const livePreview = useMemo(() => renderPreview(liveTemplate), [liveTemplate]);
  const charCount = liveTemplate.length;
  const segments = segmentCount(charCount);

  const columns: ColumnsType<SmsMessageTemplate> = [
    {
      title: 'Name',
      dataIndex: 'name',
      ellipsis: true,
      render: (name, record) => (
        <Space>
          <Tooltip title={record.isFavorite ? 'Remove from favorites' : 'Add to favorites'}>
            <span style={{ cursor: 'pointer' }} onClick={() => handleToggleFavorite(record.id)}>
              {record.isFavorite ? <StarFilled style={{ color: '#faad14' }} /> : <StarOutlined style={{ color: 'rgba(255,255,255,0.3)' }} />}
            </span>
          </Tooltip>
          <span>{name}</span>
          {record.isSystem && <Tag color="geekblue">SYSTEM</Tag>}
        </Space>
      ),
    },
    {
      title: 'Category',
      dataIndex: 'category',
      width: 120,
      render: (cat) => cat ? <Tag color={CATEGORY_COLORS[cat] || 'default'}>{cat}</Tag> : <Text type="secondary">-</Text>,
    },
    {
      title: 'Variables',
      width: 200,
      responsive: ['lg'] as any,
      render: (_, record) => (
        <Space wrap size={2}>
          {(record.variables || []).map((v) => (
            <Tag key={v} style={{ fontSize: 11 }}>{`{${v}}`}</Tag>
          ))}
          {(!record.variables || record.variables.length === 0) && <Text type="secondary">-</Text>}
        </Space>
      ),
    },
    {
      title: 'Uses',
      dataIndex: 'usageCount',
      width: 70,
      align: 'center',
      responsive: ['md'] as any,
    },
    {
      title: 'Updated',
      dataIndex: 'updatedAt',
      width: 100,
      responsive: ['md'] as any,
      render: (d) => {
        const diff = Date.now() - new Date(d).getTime();
        const mins = Math.floor(diff / 60000);
        if (mins < 60) return `${mins}m ago`;
        const hours = Math.floor(mins / 60);
        if (hours < 24) return `${hours}h ago`;
        const days = Math.floor(hours / 24);
        return `${days}d ago`;
      },
    },
    {
      title: 'Actions',
      width: 140,
      render: (_, record) => (
        <Space>
          <Tooltip title="Edit">
            <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(record)} />
          </Tooltip>
          <Tooltip title="Duplicate">
            <Button size="small" icon={<CopyOutlined />} onClick={() => openDuplicate(record)} />
          </Tooltip>
          {!record.isSystem && (
            <Tooltip title="Delete">
              <Button
                size="small"
                danger
                icon={<DeleteOutlined />}
                onClick={() => {
                  Modal.confirm({
                    title: 'Delete template?',
                    content: `This will permanently delete "${record.name}".`,
                    okText: 'Delete',
                    okType: 'danger',
                    onOk: () => handleDelete(record.id),
                  });
                }}
              />
            </Tooltip>
          )}
        </Space>
      ),
    },
  ];

  const drawerWidth = isMobile ? '100%' : 480;

  return (
    <>
      <div style={{ marginRight: drawerOpen && !isMobile ? 480 : 0, transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)' }}>
        <Space style={{ marginBottom: 16 }} wrap>
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            New Template
          </Button>
          <Input.Search
            placeholder="Search templates..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            allowClear
            style={{ width: 220 }}
          />
          <Select
            placeholder="Category"
            value={categoryFilter}
            onChange={setCategoryFilter}
            allowClear
            style={{ width: 140 }}
            options={[
              { value: 'notification', label: 'Notification' },
              { value: 'campaign', label: 'Campaign' },
              { value: 'custom', label: 'Custom' },
            ]}
          />
          <Space>
            <Switch size="small" checked={favoritesOnly} onChange={setFavoritesOnly} />
            <Text type="secondary" style={{ fontSize: 12 }}>Favorites only</Text>
          </Space>
        </Space>

        <Table
          rowKey="id"
          columns={columns}
          dataSource={templates}
          loading={loading}
          pagination={{ current: page, total, pageSize: 50, onChange: setPage, showSizeChanger: false }}
          size="middle"
          scroll={{ x: 'max-content' }}
        />
      </div>

      <Drawer
        title={editingId ? 'Edit Template' : 'New Template'}
        open={drawerOpen}
        onClose={closeDrawer}
        destroyOnHidden
        mask={false}
        width={drawerWidth}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        extra={
          <Space>
            <Button onClick={closeDrawer}>Cancel</Button>
            <Button type="primary" loading={saving} onClick={() => form.submit()}>
              {editingId ? 'Save' : 'Create'}
            </Button>
          </Space>
        }
      >
        <Form form={form} layout="vertical" onFinish={handleSave}>
          <Form.Item name="name" label="Name" rules={[{ required: true, message: 'Template name is required' }]}>
            <Input placeholder="e.g. shift-reminder-custom" maxLength={200} />
          </Form.Item>
          <Form.Item
            name="template"
            label="Message Template"
            rules={[{ required: true, message: 'Template body is required' }]}
            extra={
              <Space style={{ marginTop: 4 }}>
                <Text type="secondary" style={{ fontSize: 12 }}>
                  {charCount} / 1,600 chars
                </Text>
                <Text type="secondary" style={{ fontSize: 12 }}>
                  {segments} SMS segment{segments !== 1 ? 's' : ''}
                </Text>
                {charCount > 160 && (
                  <Text type="warning" style={{ fontSize: 12 }}>
                    Multi-part message (153 chars/segment)
                  </Text>
                )}
              </Space>
            }
          >
            <TextArea
              rows={4}
              maxLength={1600}
              placeholder="Hi {name}, your shift {shiftTitle} is coming up on {shiftDate} at {shiftTime}."
              onChange={(e) => setLiveTemplate(e.target.value)}
            />
          </Form.Item>

          {/* Live variables */}
          {liveVars.length > 0 && (
            <div style={{ marginBottom: 16 }}>
              <Text type="secondary" style={{ fontSize: 12 }}>Detected variables: </Text>
              {liveVars.map((v) => (
                <Tag key={v} color="blue" style={{ fontSize: 11 }}>{`{${v}}`}</Tag>
              ))}
            </div>
          )}

          {/* Live preview */}
          {liveTemplate && (
            <div style={{
              background: 'rgba(255,255,255,0.05)',
              padding: 12,
              borderRadius: 8,
              marginBottom: 16,
              border: '1px solid rgba(255,255,255,0.1)',
            }}>
              <Text type="secondary" style={{ fontSize: 11, display: 'block', marginBottom: 6 }}>Preview:</Text>
              <Text style={{ fontSize: 13, fontFamily: 'monospace', whiteSpace: 'pre-wrap' }}>
                {livePreview}
              </Text>
            </div>
          )}

          <Form.Item name="description" label="Description">
            <TextArea rows={2} maxLength={500} placeholder="Internal notes about when to use this template" />
          </Form.Item>
          <Form.Item name="category" label="Category">
            <Select
              placeholder="Select category"
              allowClear
              options={[
                { value: 'notification', label: 'Notification' },
                { value: 'campaign', label: 'Campaign' },
                { value: 'custom', label: 'Custom' },
              ]}
            />
          </Form.Item>
        </Form>
      </Drawer>
    </>
  );
}
