import { useState, useEffect, useCallback, useRef } from 'react';
import {
  Table,
  Button,
  Input,
  Select,
  Tag,
  Space,
  Modal,
  Drawer,
  Form,
  Popconfirm,
  message,
  Row,
  Col,
  Radio,
  Checkbox,
  Divider,
  Grid,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  SearchOutlined,
  EyeOutlined,
  SettingOutlined,
  SyncOutlined,
  BuildOutlined,
  ExclamationCircleOutlined,
  QrcodeOutlined,
} from '@ant-design/icons';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import dayjs from 'dayjs';
import { useOutletContext, useLocation } from 'react-router-dom';
import { api } from '@/lib/api';
import { useMkDocsBuild } from '@/hooks/useMkDocsBuild';
import LandingPageEditor from '@/components/landing-pages/LandingPageEditor';
import QrCodeModal from '@/components/QrCodeModal';
import type { LandingPage, EditorMode, LandingPagesListResponse, LandingPagesListParams, AppOutletContext } from '@/types/api';

const { TextArea } = Input;

const publishedOptions = [
  { value: 'true', label: 'Published' },
  { value: 'false', label: 'Draft' },
];

export default function LandingPagesPage() {
  const { building, confirmAndBuild, isSuperAdmin } = useMkDocsBuild();
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const location = useLocation();
  const [pages, setPages] = useState<LandingPage[]>([]);
  const [pagination, setPagination] = useState({ page: 1, limit: 20, total: 0, totalPages: 0 });
  const [loading, setLoading] = useState(false);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [syncing, setSyncing] = useState(false);
  const [validating, setValidating] = useState(false);
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
  const [publishedFilter, setPublishedFilter] = useState<'true' | 'false' | undefined>();
  const [createDrawerOpen, setCreateDrawerOpen] = useState(false);
  const [settingsDrawerOpen, setSettingsDrawerOpen] = useState(false);
  const [editingPage, setEditingPage] = useState<LandingPage | null>(null);
  const [editingPageId, setEditingPageId] = useState<string | null>(null);
  const [qrPage, setQrPage] = useState<LandingPage | null>(null);
  const [viewCounts, setViewCounts] = useState<Record<string, number>>({});
  const [createForm] = Form.useForm();
  const [settingsForm] = Form.useForm();

  const handleSearchChange = (value: string) => {
    setSearch(value);
    clearTimeout(searchTimerRef.current);
    searchTimerRef.current = setTimeout(() => setDebouncedSearch(value), 300);
  };

  useEffect(() => {
    return () => clearTimeout(searchTimerRef.current);
  }, []);

  // Handle navigation state from command palette — auto-open editor for a page
  useEffect(() => {
    const editPageId = (location.state as { editPageId?: string } | null)?.editPageId;
    if (!editPageId) return;
    setEditingPageId(editPageId);
    window.history.replaceState({}, '');
  }, [location.state]);

  const fetchPages = useCallback(async (params?: LandingPagesListParams) => {
    setLoading(true);
    try {
      const { data } = await api.get<LandingPagesListResponse>('/pages', {
        params: {
          page: params?.page ?? pagination.page,
          limit: params?.limit ?? pagination.limit,
          search: params?.search ?? (debouncedSearch || undefined),
          published: params?.published ?? publishedFilter,
        },
      });
      setPages(data.pages);
      setPagination(data.pagination);
    } catch {
      message.error('Failed to load pages');
    } finally {
      setLoading(false);
    }
  }, [pagination.page, pagination.limit, debouncedSearch, publishedFilter]);

  useEffect(() => {
    fetchPages({ page: 1 });
  }, [debouncedSearch, publishedFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    api.get<Record<string, number>>('/pages/view-counts')
      .then(({ data }) => setViewCounts(data))
      .catch(() => {});
  }, []);

  const handleTableChange = (pag: TablePaginationConfig) => {
    fetchPages({ page: pag.current ?? 1, limit: pag.pageSize ?? 20 });
  };

  const handleCreate = async (values: { title: string; description?: string; editorMode?: EditorMode }) => {
    try {
      const { data } = await api.post<LandingPage>('/pages', values);
      message.success('Page created');
      setCreateDrawerOpen(false);
      createForm.resetFields();
      setEditingPageId(data.id);
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to create page';
      message.error(msg);
    }
  };

  const handleSyncOverrides = async () => {
    setSyncing(true);
    try {
      const { data } = await api.post<{ imported: number; updated: number; stubs: number }>('/pages/sync');
      if (data.imported > 0 || data.updated > 0 || data.stubs > 0) {
        message.success(`Synced: ${data.imported} imported, ${data.updated} updated, ${data.stubs} stubs created`);
        fetchPages();
      } else {
        message.info('No new overrides to sync');
      }
    } catch {
      message.error('Failed to sync overrides');
    } finally {
      setSyncing(false);
    }
  };

  const handleValidateExports = async () => {
    setValidating(true);
    try {
      const { data } = await api.post<{validated: number; repaired: number; errors: Array<{pageId: string; slug: string; error: string}>}>('/pages/validate');
      if (data.repaired > 0 || data.errors.length > 0) {
        const msg = `Validated ${data.validated} pages: ${data.repaired} repaired`;
        data.errors.length > 0 ? message.warning(`${msg}, ${data.errors.length} errors`) : message.success(msg);
        fetchPages();
      } else {
        message.info(`Validated ${data.validated} pages - all OK`);
      }
    } catch {
      message.error('Failed to validate exports');
    } finally {
      setValidating(false);
    }
  };

  const handleSettingsSave = async (values: Record<string, unknown>) => {
    if (!editingPage) return;
    try {
      await api.put(`/pages/${editingPage.id}`, values);
      message.success('Page settings updated');
      setSettingsDrawerOpen(false);
      setEditingPage(null);
      settingsForm.resetFields();
      fetchPages();
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to update page';
      message.error(msg);
    }
  };

  const handleTogglePublished = async (page: LandingPage) => {
    try {
      await api.put(`/pages/${page.id}`, { published: !page.published });
      message.success(page.published ? 'Page unpublished' : 'Page published');
      fetchPages();
    } catch {
      message.error('Failed to update page');
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/pages/${id}`);
      message.success('Page deleted');
      fetchPages();
    } catch {
      message.error('Failed to delete page');
    }
  };

  // Critical MkDocs override pages that need a confirmation before editing
  const CRITICAL_SLUGS = ['main', 'custom'];

  const handleEditClick = (page: LandingPage) => {
    if (CRITICAL_SLUGS.includes(page.slug)) {
      Modal.confirm({
        title: 'Edit critical MkDocs template?',
        icon: <ExclamationCircleOutlined />,
        content: (
          <div>
            <p>
              <strong>{page.title}</strong> ({page.mkdocsPath || page.slug}) is a critical MkDocs
              override template. Changes to this file affect the entire documentation site.
            </p>
            <p>Are you sure you want to edit it?</p>
          </div>
        ),
        okText: 'Edit',
        okType: 'danger',
        cancelText: 'Cancel',
        onOk: () => setEditingPageId(page.id),
      });
    } else {
      setEditingPageId(page.id);
    }
  };

  const openSettings = (page: LandingPage) => {
    setEditingPage(page);
    settingsForm.setFieldsValue({
      title: page.title,
      description: page.description,
      listed: page.listed ?? false,
      mkdocsPath: page.mkdocsPath,
      mkdocsExportMode: page.mkdocsExportMode,
      mkdocsHideNav: page.mkdocsHideNav,
      mkdocsHideToc: page.mkdocsHideToc,
      mkdocsSkipExport: page.mkdocsSkipExport,
      seoTitle: page.seoTitle,
      seoDescription: page.seoDescription,
      seoImage: page.seoImage,
    });
    setSettingsDrawerOpen(true);
  };

  const columns: ColumnsType<LandingPage> = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      render: (title: string, record: LandingPage) => (
        <div>
          <span style={{ fontWeight: 500 }}>{title}</span>
          <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>/p/{record.slug}</div>
        </div>
      ),
    },
    {
      title: 'Editor',
      dataIndex: 'editorMode',
      key: 'editorMode',
      render: (mode: EditorMode) => (
        <Tag color={mode === 'VISUAL' ? 'green' : 'blue'}>
          {mode === 'VISUAL' ? 'Visual' : 'Code'}
        </Tag>
      ),
      responsive: ['sm'],
    },
    {
      title: 'Status',
      dataIndex: 'published',
      key: 'published',
      render: (published: boolean, record: LandingPage) => (
        <Space size={4}>
          <Tag color={published ? 'green' : 'default'}>{published ? 'Published' : 'Draft'}</Tag>
          {record.listed && <Tag color="blue">Listed</Tag>}
        </Space>
      ),
    },
    {
      title: 'MkDocs',
      dataIndex: 'mkdocsPath',
      key: 'mkdocsPath',
      render: (_: string | null, record: LandingPage) => (
        <div>
          <div>{record.mkdocsPath || '--'}</div>
          {record.mkdocsStubPath && (
            <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.45)' }}>{record.mkdocsStubPath}</div>
          )}
        </div>
      ),
      responsive: ['lg'],
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'createdAt',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD'),
      responsive: ['md'],
    },
    {
      title: 'Updated',
      dataIndex: 'updatedAt',
      key: 'updatedAt',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD'),
      responsive: ['md'],
    },
    {
      title: 'Views (30d)',
      key: 'views',
      render: (_: unknown, record: LandingPage) => viewCounts[record.slug] ?? 0,
      responsive: ['md'],
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: LandingPage) => (
        <Space>
          <Button
            type="link"
            size="small"
            icon={<EditOutlined />}
            onClick={() => handleEditClick(record)}
            title={record.editorMode === 'CODE' ? 'Edit code' : 'Edit in builder'}
          />
          <Button
            type="link"
            size="small"
            icon={<SettingOutlined />}
            onClick={() => openSettings(record)}
            title="Page settings"
          />
          {record.published && (
            <>
              <Button
                type="link"
                size="small"
                icon={<EyeOutlined />}
                onClick={() => window.open(`/p/${record.slug}`, '_blank')}
                title="View page"
              />
              <Button
                type="link"
                size="small"
                icon={<QrcodeOutlined />}
                onClick={() => setQrPage(record)}
                title="QR code"
              />
            </>
          )}
          {record.published ? (
            <Popconfirm
              title="Unpublish this page?"
              description="It will no longer be publicly accessible."
              onConfirm={() => handleTogglePublished(record)}
            >
              <Button type="link" size="small">
                Unpublish
              </Button>
            </Popconfirm>
          ) : (
            <Button
              type="link"
              size="small"
              onClick={() => handleTogglePublished(record)}
            >
              Publish
            </Button>
          )}
          <Popconfirm
            title="Delete this page?"
            description="This action cannot be undone."
            onConfirm={() => handleDelete(record.id)}
          >
            <Button type="link" size="small" danger icon={<DeleteOutlined />} title="Delete" />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  // Set fullBleed when editor is open, title when in list mode
  useEffect(() => {
    if (editingPageId) {
      setPageHeader({ fullBleed: true });
    } else {
      setPageHeader({ title: 'Landing Pages' });
    }
    return () => setPageHeader(null);
  }, [editingPageId, setPageHeader]);

  // If editing a page, show the editor instead of the list
  if (editingPageId) {
    return (
      <LandingPageEditor
        pageId={editingPageId}
        onClose={() => {
          setEditingPageId(null);
          fetchPages(); // Refresh table data
        }}
      />
    );
  }

  const anyDrawerOpen = createDrawerOpen || settingsDrawerOpen;
  const activeDrawerWidth = isMobile ? 0 : (createDrawerOpen ? 520 : settingsDrawerOpen ? 560 : 0);

  return (
    <>
      <div style={{ marginRight: anyDrawerOpen ? activeDrawerWidth : 0, transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)' }}>
        <Row justify="end" align="middle" style={{ marginBottom: 16 }}>
          <Col>
            <Space>
              {isSuperAdmin && (
                <Button
                  icon={<BuildOutlined />}
                  loading={building}
                  onClick={confirmAndBuild}
                >
                  Build Site
                </Button>
              )}
              <Button
                icon={<SyncOutlined spin={syncing} />}
                loading={syncing}
                onClick={handleSyncOverrides}
              >
                Sync Overrides
              </Button>
              <Button
                icon={<SyncOutlined spin={validating} />}
                loading={validating}
                onClick={handleValidateExports}
                title="Validate MkDocs export files and repair if missing"
              >
                Validate Exports
              </Button>
              <Button
                type="primary"
                icon={<PlusOutlined />}
                onClick={() => setCreateDrawerOpen(true)}
              >
                Create Page
              </Button>
            </Space>
          </Col>
        </Row>

        <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
          <Col xs={24} sm={12} md={8}>
            <Input
              placeholder="Search by title or description"
              prefix={<SearchOutlined />}
              value={search}
              onChange={(e) => handleSearchChange(e.target.value)}
              allowClear
            />
          </Col>
          <Col xs={12} sm={7} md={4}>
            <Select
              placeholder="Status"
              options={publishedOptions}
              value={publishedFilter}
              onChange={setPublishedFilter}
              allowClear
              style={{ width: '100%' }}
            />
          </Col>
        </Row>

        <Table<LandingPage>
          columns={columns}
          dataSource={pages}
          rowKey="id"
          loading={loading}
          scroll={{ x: 'max-content' }}
          pagination={{
            current: pagination.page,
            pageSize: pagination.limit,
            total: pagination.total,
            showSizeChanger: true,
            showTotal: (total) => `${total} pages`,
          }}
          onChange={handleTableChange}
          locale={{ emptyText: 'No landing pages yet. Create your first page to get started.' }}
        />
      </div>

      {/* Create Drawer */}
      <Drawer
        title="Create Landing Page"
        open={createDrawerOpen}
        destroyOnHidden
        mask={false}
        width={isMobile ? '100%' : 520}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setCreateDrawerOpen(false);
          createForm.resetFields();
        }}
        extra={
          <Space>
            <Button onClick={() => { setCreateDrawerOpen(false); createForm.resetFields(); }}>
              Cancel
            </Button>
            <Button type="primary" onClick={() => createForm.submit()}>
              Create & Edit
            </Button>
          </Space>
        }
      >
        <Form form={createForm} onFinish={handleCreate} layout="vertical" initialValues={{ editorMode: 'VISUAL' }}>
          <Form.Item
            name="title"
            label="Title"
            rules={[{ required: true, message: 'Title is required' }]}
          >
            <Input placeholder="e.g. Join Our Campaign" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <TextArea rows={3} />
          </Form.Item>
          <Form.Item name="editorMode" label="Editor Mode">
            <Radio.Group>
              <Radio.Button value="VISUAL">Visual Editor</Radio.Button>
              <Radio.Button value="CODE">Code Editor</Radio.Button>
            </Radio.Group>
          </Form.Item>
        </Form>
      </Drawer>

      {/* QR Code Modal */}
      {qrPage && (
        <QrCodeModal
          open={!!qrPage}
          onClose={() => setQrPage(null)}
          url={`${window.location.origin}/p/${qrPage.slug}`}
          title={qrPage.title}
        />
      )}

      {/* Settings Drawer */}
      <Drawer
        title="Page Settings"
        open={settingsDrawerOpen}
        destroyOnHidden
        mask={false}
        width={isMobile ? '100%' : 560}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setSettingsDrawerOpen(false);
          setEditingPage(null);
          settingsForm.resetFields();
        }}
        extra={
          <Space>
            <Button onClick={() => { setSettingsDrawerOpen(false); setEditingPage(null); settingsForm.resetFields(); }}>
              Cancel
            </Button>
            <Button type="primary" onClick={() => settingsForm.submit()}>
              Save
            </Button>
          </Space>
        }
      >
        <Form form={settingsForm} onFinish={handleSettingsSave} layout="vertical">
          <Form.Item
            name="title"
            label="Title"
            rules={[{ required: true, message: 'Title is required' }]}
          >
            <Input placeholder="e.g. Join Our Campaign" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <TextArea rows={2} />
          </Form.Item>
          <Form.Item name="seoTitle" label="SEO Title">
            <Input />
          </Form.Item>
          <Form.Item name="seoDescription" label="SEO Description">
            <TextArea rows={2} />
          </Form.Item>
          <Form.Item name="seoImage" label="SEO Image URL">
            <Input placeholder="https://..." />
          </Form.Item>

          <Form.Item
            name="listed"
            valuePropName="checked"
            help="Show this page in the public /pages directory when published."
          >
            <Checkbox>List in Pages Index</Checkbox>
          </Form.Item>

          <Divider>MkDocs Integration</Divider>

          <Form.Item
            name="mkdocsSkipExport"
            valuePropName="checked"
            help="When enabled, this page will not be exported to MkDocs even when published. Use for pages that should only be accessible via /p/:slug."
          >
            <Checkbox>Skip MkDocs Export</Checkbox>
          </Form.Item>

          <Form.Item noStyle shouldUpdate={(prev, cur) => prev.mkdocsSkipExport !== cur.mkdocsSkipExport}>
            {({ getFieldValue }) =>
              !getFieldValue('mkdocsSkipExport') && (
                <>
                  <Form.Item name="mkdocsPath" label="Override Path">
                    <Input placeholder="e.g. about.html" />
                  </Form.Item>
                  <Form.Item
                    name="mkdocsExportMode"
                    valuePropName="checked"
                    getValueFromEvent={(e: { target: { checked: boolean } }) => e.target.checked ? 'STANDALONE' : 'THEMED'}
                    getValueProps={(value: string) => ({ checked: value === 'STANDALONE' })}
                    help="Publish as a full HTML page with no MkDocs header, footer, or theme (like lander.html)"
                  >
                    <Checkbox>Full page MkDocs</Checkbox>
                  </Form.Item>
                  <Form.Item noStyle shouldUpdate={(prev, cur) => prev.mkdocsExportMode !== cur.mkdocsExportMode}>
                    {({ getFieldValue }) =>
                      getFieldValue('mkdocsExportMode') !== 'STANDALONE' && (
                        <>
                          <Form.Item name="mkdocsHideNav" valuePropName="checked">
                            <Checkbox>Hide navigation sidebar</Checkbox>
                          </Form.Item>
                          <Form.Item name="mkdocsHideToc" valuePropName="checked">
                            <Checkbox>Hide table of contents</Checkbox>
                          </Form.Item>
                        </>
                      )
                    }
                  </Form.Item>
                </>
              )
            }
          </Form.Item>
        </Form>
      </Drawer>
    </>
  );
}
