import { useState, useEffect, useCallback, useRef } from 'react';
import { Button, Switch, Space, Typography, message, Spin, Tag, Grid, Result, theme, App } from 'antd';
import { ArrowLeftOutlined, SaveOutlined, EyeOutlined } from '@ant-design/icons';
import Editor from '@monaco-editor/react';
import { api } from '@/lib/api';
import GrapesJSEditor from '@/components/GrapesJSEditor';
import type { GrapesJSEditorHandle } from '@/components/GrapesJSEditor';
import type { LandingPage, PageBlock } from '@/types/api';

const { Text } = Typography;

interface LandingPageEditorProps {
  pageId: string;
  onClose: () => void;
}

export default function LandingPageEditor({ pageId, onClose }: LandingPageEditorProps) {
  const [page, setPage] = useState<LandingPage | null>(null);
  const [blocks, setBlocks] = useState<PageBlock[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [codeContent, setCodeContent] = useState('');
  const editorRef = useRef<GrapesJSEditorHandle>(null);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const { token } = theme.useToken();
  const { modal } = App.useApp();

  const isCodeMode = page?.editorMode === 'CODE';

  useEffect(() => {
    const fetchData = async () => {
      try {
        if (isCodeMode) {
          // CODE mode only needs page data
          const pageRes = await api.get<LandingPage>(`/pages/${pageId}`);
          setPage(pageRes.data);
          setCodeContent(pageRes.data.htmlOutput || '');
        } else {
          const [pageRes, blocksRes] = await Promise.all([
            api.get<LandingPage>(`/pages/${pageId}`),
            api.get<PageBlock[]>('/page-blocks'),
          ]);
          setPage(pageRes.data);
          setBlocks(blocksRes.data);
          setCodeContent(pageRes.data.htmlOutput || '');
        }
      } catch {
        message.error('Failed to load page');
        onClose();
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, [pageId, isCodeMode, onClose]);

  const handleSaveVisual = useCallback(async (data: { projectData: Record<string, unknown>; html: string; css: string }) => {
    if (!page) return;
    setSaving(true);
    try {
      const { data: updated } = await api.put<LandingPage>(`/pages/${page.id}`, {
        blocks: data.projectData,
        htmlOutput: data.html,
        cssOutput: data.css,
      });
      setPage(updated);
      message.success('Page saved');
    } catch {
      message.error('Failed to save page');
    } finally {
      setSaving(false);
    }
  }, [page]);

  const handleSaveCode = useCallback(async () => {
    if (!page) return;
    setSaving(true);
    try {
      const { data: updated } = await api.put<LandingPage>(`/pages/${page.id}`, {
        htmlOutput: codeContent,
      });
      setPage(updated);
      message.success('Page saved');
    } catch {
      message.error('Failed to save page');
    } finally {
      setSaving(false);
    }
  }, [page, codeContent]);

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

  // Ctrl+S handler for CODE mode
  useEffect(() => {
    if (!isCodeMode) return;
    const handler = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        handleSaveCode();
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [isCodeMode, handleSaveCode]);

  const handleClose = () => {
    // Check if there are unsaved changes
    if (page && isCodeMode && codeContent !== page.htmlOutput) {
      modal.confirm({
        title: 'Unsaved Changes',
        content: 'You have unsaved changes. Are you sure you want to discard them?',
        okText: 'Discard',
        cancelText: 'Continue Editing',
        okType: 'danger',
        onOk: () => onClose(),
      });
    } else {
      onClose();
    }
  };

  if (loading) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 'calc(100vh - 64px)' }}>
        <Spin size="large" />
      </div>
    );
  }

  if (!page) return null;

  if (isMobile) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: 'calc(100vh - 64px)', padding: 24 }}>
        <Result
          status="info"
          title="Desktop Required"
          subTitle={`The ${isCodeMode ? 'code' : 'page'} editor requires a desktop browser. Please switch to a larger screen to edit this page.`}
          extra={
            <Button type="primary" onClick={onClose}>
              Back to Pages
            </Button>
          }
        />
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: 'calc(100vh - 64px)', background: token.colorBgBase }}>
      {/* Toolbar */}
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          padding: '8px 16px',
          borderBottom: `1px solid ${token.colorBorderSecondary}`,
          background: token.colorBgBase,
          zIndex: 10,
          flexShrink: 0,
        }}
      >
        <Space>
          <Button
            type="text"
            icon={<ArrowLeftOutlined />}
            onClick={handleClose}
            aria-label="Close editor"
            style={{ color: '#fff' }}
          />
          <Text strong style={{ color: '#fff', fontSize: 16 }}>{page.title}</Text>
          <Text style={{ color: 'rgba(255,255,255,0.45)', fontSize: 12 }}>/p/{page.slug}</Text>
          <Tag color={isCodeMode ? 'blue' : 'green'}>{isCodeMode ? 'Code' : 'Visual'}</Tag>
        </Space>
        <Space>
          <Space size={4}>
            <Text style={{ color: 'rgba(255,255,255,0.65)', fontSize: 13 }}>Published</Text>
            <Switch
              checked={page.published}
              onChange={handleTogglePublished}
              size="small"
            />
          </Space>
          {page.published && (
            <Tag color="green">Live</Tag>
          )}
          {page.published && (
            <Button
              size="small"
              icon={<EyeOutlined />}
              onClick={() => window.open(`/p/${page.slug}`, '_blank')}
            >
              Preview
            </Button>
          )}
          <Button
            type="primary"
            size="small"
            icon={<SaveOutlined />}
            loading={saving}
            onClick={() => {
              if (isCodeMode) {
                handleSaveCode();
              } else {
                editorRef.current?.triggerSave();
              }
            }}
          >
            Save
          </Button>
        </Space>
      </div>

      {/* Editor — conditional on mode */}
      {isCodeMode ? (
        <div style={{ flex: 1, overflow: 'hidden' }}>
          <Editor
            height="100%"
            defaultLanguage="html"
            theme="vs-dark"
            value={codeContent}
            onChange={(value) => setCodeContent(value ?? '')}
            options={{
              wordWrap: 'on',
              minimap: { enabled: false },
              fontSize: 14,
              scrollBeyondLastLine: false,
              automaticLayout: true,
            }}
          />
        </div>
      ) : (
        <GrapesJSEditor
          ref={editorRef}
          initialData={page.blocks as Record<string, unknown>}
          onSave={handleSaveVisual}
          customBlocks={blocks}
        />
      )}
    </div>
  );
}
