import { test, expect, Page } from '@playwright/test';

const LOGIN_URL = 'http://192.168.1.105:8080/';
const EDITOR_URL = 'http://192.168.1.105:8080/site-builder/?site_id=1';
const LIVE_URL = 'http://testsite.local/';
const USERNAME = 'root';
const PASSWORD = 'Jk@44351100!';

// Helper: login to WHP
async function login(page: Page) {
  await page.goto(LOGIN_URL);
  if (page.url().includes('login')) {
    await page.fill('input[name="user"]', USERNAME);
    await page.fill('input[name="password"]', PASSWORD);
    await page.click('button[type="submit"], input[type="submit"]');
    await page.waitForURL('**/index.php**');
  }
}

// Helper: open site builder
async function openEditor(page: Page) {
  await page.goto(EDITOR_URL);
  await page.waitForSelector('.editor-canvas', { timeout: 10000 });
  await page.waitForTimeout(2000); // Let Craft.js initialize
}

// Helper: add a block by double-clicking it in the blocks panel
async function addBlock(page: Page, blockLabel: string) {
  // Make sure blocks tab is active
  const blocksTab = page.locator('.panel-tab', { hasText: 'Blocks' });
  await blocksTab.click();
  await page.waitForTimeout(300);

  // Expand ALL collapsed categories first
  let collapsed = page.locator('.block-category-header.collapsed');
  let count = await collapsed.count();
  for (let i = 0; i < count; i++) {
    await collapsed.nth(0).click(); // Always click first collapsed (it changes after click)
    await page.waitForTimeout(200);
    collapsed = page.locator('.block-category-header.collapsed'); // Re-query
  }
  await page.waitForTimeout(300);

  // Find the block by title attribute
  const block = page.locator(`.block-item[title*="${blockLabel}"]`).first();

  // Scroll it into view
  await block.scrollIntoViewIfNeeded();
  await page.waitForTimeout(200);

  await block.dblclick({ force: true });
  await page.waitForTimeout(800);
}

// Helper: check console for errors
async function checkNoErrors(page: Page): Promise<string[]> {
  const errors: string[] = [];
  page.on('pageerror', (error) => {
    errors.push(error.message);
  });
  return errors;
}

// Helper: click on an element in the canvas
async function selectCanvasElement(page: Page, selector: string) {
  const el = page.locator(`.canvas-device-frame ${selector}`).first();
  if (await el.count() > 0) {
    await el.click();
    await page.waitForTimeout(500);
  }
  return el;
}

// Helper: check that the Styles panel shows controls (not "No controls")
async function verifyStylesPanel(page: Page) {
  const stylesTab = page.locator('.panel-tab', { hasText: 'Styles' });
  await stylesTab.click();
  await page.waitForTimeout(300);
  const panelContent = page.locator('.panel-right .panel-content');
  const text = await panelContent.textContent();
  return text || '';
}

// ============================================================
// TESTS
// ============================================================

test.describe('Site Builder - Authentication', () => {
  test('can login to WHP', async ({ page }) => {
    await login(page);
    expect(page.url()).toContain('index.php');
  });

  test('can open site builder', async ({ page }) => {
    await login(page);
    await openEditor(page);
    expect(page.url()).toContain('site-builder');
    await expect(page.locator('.editor-canvas')).toBeVisible();
  });
});

test.describe('Site Builder - Block Categories', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('has all 5 block categories', async ({ page }) => {
    const categories = page.locator('.block-category-header');
    const texts = await categories.allTextContents();
    expect(texts.join(' ')).toContain('Basic');
    expect(texts.join(' ')).toContain('Layout');
    expect(texts.join(' ')).toContain('Sections');
    expect(texts.join(' ')).toContain('Media');
    expect(texts.join(' ')).toContain('Forms');
  });

  test('has correct block count', async ({ page }) => {
    // Expand all categories
    const headers = page.locator('.block-category-header.collapsed');
    for (let i = 0; i < await headers.count(); i++) {
      await headers.nth(i).click();
      await page.waitForTimeout(200);
    }
    const blocks = page.locator('.block-item');
    const count = await blocks.count();
    expect(count).toBeGreaterThanOrEqual(35);
  });
});

test.describe('Site Builder - Basic Blocks', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('can add Heading block', async ({ page }) => {
    await addBlock(page, 'Heading');
    const heading = page.locator('.canvas-device-frame h2').first();
    await expect(heading).toBeVisible();
  });

  test('can add Text block', async ({ page }) => {
    await addBlock(page, 'Text');
    const text = page.locator('.canvas-device-frame p');
    expect(await text.count()).toBeGreaterThan(0);
  });

  test('can add Button block', async ({ page }) => {
    await addBlock(page, 'Button');
    const button = page.locator('.canvas-device-frame a[style*="inline-block"]');
    expect(await button.count()).toBeGreaterThan(0);
  });

  test('can add Divider block', async ({ page }) => {
    await addBlock(page, 'Divider');
    const divider = page.locator('.canvas-device-frame hr');
    expect(await divider.count()).toBeGreaterThan(0);
  });

  test('can add Spacer block', async ({ page }) => {
    await addBlock(page, 'Spacer');
    const spacer = page.locator('.canvas-device-frame div[style*="height"]');
    expect(await spacer.count()).toBeGreaterThan(0);
  });

  test('can add Icon block', async ({ page }) => {
    await addBlock(page, 'Icon');
    const icon = page.locator('.canvas-device-frame .fa');
    expect(await icon.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Layout Blocks', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('can add 2 Column layout', async ({ page }) => {
    await addBlock(page, '2 Columns');
    const flexContainer = page.locator('.canvas-device-frame div[style*="display: flex"]');
    expect(await flexContainer.count()).toBeGreaterThan(0);
  });

  test('can add 4 Column layout', async ({ page }) => {
    await addBlock(page, '4 Columns');
    await page.waitForTimeout(500);
    const flexContainer = page.locator('.canvas-device-frame div[style*="display: flex"]');
    expect(await flexContainer.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Section Blocks', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('can add Hero block', async ({ page }) => {
    await addBlock(page, 'Hero');
    const hero = page.locator('.canvas-device-frame section[style*="min-height"]');
    expect(await hero.count()).toBeGreaterThan(0);
  });

  test('Hero shows settings when selected', async ({ page }) => {
    await addBlock(page, 'Hero');
    await page.locator('.canvas-device-frame section[style*="min-height"]').first().click();
    await page.waitForTimeout(500);
    const panelText = await verifyStylesPanel(page);
    expect(panelText).toContain('Hero');
    expect(panelText).toContain('Heading');
  });

  test('can add Pricing Table', async ({ page }) => {
    await addBlock(page, 'Pricing');
    await page.waitForTimeout(500);
    const pricing = page.locator('.canvas-device-frame div[style*="flex"]');
    expect(await pricing.count()).toBeGreaterThan(0);
  });

  test('can add Accordion', async ({ page }) => {
    await addBlock(page, 'Accordion');
    await page.waitForTimeout(500);
    // Accordion should have clickable panels
    const panels = page.locator('.canvas-device-frame div[style*="cursor: pointer"]');
    expect(await panels.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Media Blocks', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('can add Image block', async ({ page }) => {
    await addBlock(page, 'Image');
    const img = page.locator('.canvas-device-frame img');
    expect(await img.count()).toBeGreaterThan(0);
  });

  test('Image shows upload controls when selected', async ({ page }) => {
    await addBlock(page, 'Image');
    await page.locator('.canvas-device-frame img').first().click();
    await page.waitForTimeout(500);
    const panelText = await verifyStylesPanel(page);
    expect(panelText.toLowerCase()).toContain('image');
  });

  test('can add Video block', async ({ page }) => {
    await addBlock(page, 'Video');
    await page.waitForTimeout(500);
    // Video block should render something (placeholder or iframe)
    const canvas = page.locator('.canvas-device-frame');
    expect(await canvas.locator('*').count()).toBeGreaterThan(1);
  });
});

test.describe('Site Builder - Form Blocks', () => {
  test.beforeEach(async ({ page }) => {
    await login(page);
    await openEditor(page);
  });

  test('can add Contact Form', async ({ page }) => {
    await addBlock(page, 'Contact Form');
    await page.waitForTimeout(500);
    const form = page.locator('.canvas-device-frame form, .canvas-device-frame input');
    expect(await form.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Save and Load', () => {
  test('can save and reload', async ({ page }) => {
    await login(page);
    await openEditor(page);

    // Add a heading with unique text
    await addBlock(page, 'Heading');
    await page.waitForTimeout(500);

    // Click Save
    await page.locator('button', { hasText: 'Save' }).click();
    await page.waitForTimeout(2000);

    // Reload
    await page.goto(EDITOR_URL);
    await page.waitForSelector('.editor-canvas', { timeout: 10000 });
    await page.waitForTimeout(3000);

    // Verify canvas has content
    const canvas = page.locator('.canvas-device-frame');
    const content = await canvas.textContent();
    expect(content?.length).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Publish', () => {
  test('can publish site', async ({ page }) => {
    await login(page);
    await openEditor(page);

    // Click Publish
    const publishBtn = page.locator('button', { hasText: 'Publish' });
    if (await publishBtn.count() > 0) {
      await publishBtn.click();
      await page.waitForTimeout(3000);
    }

    // Check live site
    await page.goto(LIVE_URL);
    await page.waitForTimeout(2000);
    const body = await page.textContent('body');
    expect(body?.length).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - No Console Errors', () => {
  test('editor loads without JS errors', async ({ page }) => {
    const errors: string[] = [];
    page.on('pageerror', (error) => {
      // Ignore favicon 404 and non-critical errors
      if (!error.message.includes('favicon')) {
        errors.push(error.message);
      }
    });

    await login(page);
    await openEditor(page);
    await page.waitForTimeout(3000);

    expect(errors).toHaveLength(0);
  });
});

test.describe('Site Builder - Color Controls', () => {
  test('Hero has full color picker (not just presets)', async ({ page }) => {
    await login(page);
    await openEditor(page);
    await addBlock(page, 'Hero');
    await page.locator('.canvas-device-frame section').first().click();
    await page.waitForTimeout(500);

    // Should have <input type="color"> for full spectrum
    const colorInputs = page.locator('.panel-right input[type="color"]');
    expect(await colorInputs.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Multi-Page', () => {
  test('can create and switch pages', async ({ page }) => {
    await login(page);
    await openEditor(page);

    // Go to Pages tab
    await page.locator('.panel-tab', { hasText: 'Pages' }).click();
    await page.waitForTimeout(300);

    // Check for Add Page button
    const addPageBtn = page.locator('button, div', { hasText: /add page/i });
    expect(await addPageBtn.count()).toBeGreaterThan(0);
  });
});

test.describe('Site Builder - Templates', () => {
  test('template modal opens and shows templates', async ({ page }) => {
    await login(page);
    await openEditor(page);

    // Click Templates button
    await page.locator('button', { hasText: 'Templates' }).click();
    await page.waitForTimeout(1000);

    // Should see template cards
    const modal = page.locator('[style*="position: fixed"]');
    expect(await modal.count()).toBeGreaterThan(0);

    // Close with Escape
    await page.keyboard.press('Escape');
  });
});

test.describe('Site Builder - Header/Footer', () => {
  test('header and footer zones show on canvas', async ({ page }) => {
    await login(page);
    await openEditor(page);

    // Should see zone preview areas
    const zones = page.locator('[data-zone-preview]');
    // At minimum the footer zone should show (header may be empty)
    expect(await zones.count()).toBeGreaterThanOrEqual(0);
  });
});
