import { useState, useEffect, useCallback } from 'react';
import {
  Typography,
  Steps,
  Form,
  Input,
  Switch,
  Button,
  Card,
  Space,
  Descriptions,
  Tag,
  Alert,
  InputNumber,
  Result,
  Progress,
  Table,
} from 'antd';
import { SyncOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { api } from '@/lib/api';
import type { Instance } from '@/types/api';

interface WizardData {
  name: string;
  slug: string;
  domain: string;
  adminEmail: string;
  enableMedia: boolean;
  enableChat: boolean;
  enableGancio: boolean;
  enableListmonk: boolean;
  enableMonitoring: boolean;
  enableDevTools: boolean;
  enablePayments: boolean;
  enableMeet: boolean;
  enableSms: boolean;
  enableSocial: boolean;
  enablePeople: boolean;
  enableAnalytics: boolean;
  jvbAdvertiseIp: string;
  smtpHost: string;
  smtpPort: number;
  smtpUser: string;
  smtpFrom: string;
  emailTestMode: boolean;
  enablePangolin: boolean;
  pangolinEndpoint: string;
  pangolinNewtId: string;
  pangolinNewtSecret: string;
  notes: string;
}

const defaultData: WizardData = {
  name: '',
  slug: '',
  domain: '',
  adminEmail: '',
  enableMedia: false,
  enableChat: false,
  enableGancio: false,
  enableListmonk: false,
  enableMonitoring: false,
  enableDevTools: false,
  enablePayments: false,
  enableMeet: false,
  enableSms: false,
  enableSocial: false,
  enablePeople: false,
  enableAnalytics: false,
  jvbAdvertiseIp: '',
  smtpHost: '',
  smtpPort: 587,
  smtpUser: '',
  smtpFrom: '',
  emailTestMode: true,
  enablePangolin: false,
  pangolinEndpoint: '',
  pangolinNewtId: '',
  pangolinNewtSecret: '',
  notes: '',
};

/** Parse provisioning step from statusMessage like "Step 5/13: Rendering configuration files" */
function parseProvisioningStep(msg: string | null | undefined): { current: number; total: number; description: string } | null {
  if (!msg) return null;
  const match = msg.match(/Step (\d+)\/(\d+): (.+)/);
  if (match) {
    return { current: parseInt(match[1], 10), total: parseInt(match[2], 10), description: match[3] };
  }
  return null;
}

export default function CreateWizardPage() {
  const navigate = useNavigate();
  const [current, setCurrent] = useState(0);
  const [data, setData] = useState<WizardData>(defaultData);
  const [creating, setCreating] = useState(false);
  const [createdId, setCreatedId] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [form] = Form.useForm();

  // Provisioning tracking
  const [provisioningInstance, setProvisioningInstance] = useState<Instance | null>(null);

  const update = (fields: Partial<WizardData>) => setData((prev) => ({ ...prev, ...fields }));

  const autoSlug = (name: string) => {
    return name
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
  };

  const handleCreate = async () => {
    setCreating(true);
    setError(null);
    try {
      const { data: result } = await api.post('/instances', data);
      setCreatedId(result.data.id);
      setProvisioningInstance(result.data);
    } catch (err: unknown) {
      const resp = (err as { response?: { data?: { error?: { message?: string } } } })?.response
        ?.data?.error;
      setError(resp?.message || 'Failed to create instance');
    } finally {
      setCreating(false);
    }
  };

  // Poll for provisioning progress
  const pollStatus = useCallback(async () => {
    if (!createdId) return;
    try {
      const { data: result } = await api.get(`/instances/${createdId}`);
      setProvisioningInstance(result.data);
    } catch {
      // Silently fail — will retry on next poll
    }
  }, [createdId]);

  useEffect(() => {
    if (!createdId) return;
    if (provisioningInstance?.status === 'RUNNING' || provisioningInstance?.status === 'STOPPED') return;
    // Don't poll if error (user needs to decide what to do)
    if (provisioningInstance?.status === 'ERROR') return;

    const interval = setInterval(pollStatus, 3_000);
    return () => clearInterval(interval);
  }, [createdId, provisioningInstance?.status, pollStatus]);

  const handleRetryProvision = async () => {
    if (!createdId) return;
    try {
      await api.post(`/instances/${createdId}/provision`);
      setProvisioningInstance((prev) =>
        prev ? { ...prev, status: 'PROVISIONING', statusMessage: 'Retrying provisioning...' } : prev
      );
    } catch {
      setError('Failed to retry provisioning');
    }
  };

  const steps = [
    {
      title: 'Basic Info',
      content: (
        <Form layout="vertical" form={form}>
          <Form.Item label="Campaign Name" required>
            <Input
              value={data.name}
              onChange={(e) => {
                update({ name: e.target.value, slug: autoSlug(e.target.value) });
              }}
              placeholder="Better Edmonton"
            />
          </Form.Item>
          <Form.Item label="Slug" required help="URL-safe identifier (auto-generated)">
            <Input
              value={data.slug}
              onChange={(e) => update({ slug: e.target.value })}
              placeholder="better-edmonton"
            />
          </Form.Item>
          <Form.Item label="Domain" required>
            <Input
              value={data.domain}
              onChange={(e) => update({ domain: e.target.value })}
              placeholder="betteredmonton.org"
            />
          </Form.Item>
          <Form.Item label="Admin Email" required>
            <Input
              value={data.adminEmail}
              onChange={(e) => update({ adminEmail: e.target.value })}
              placeholder="admin@betteredmonton.org"
              type="email"
            />
          </Form.Item>
          <Form.Item label="Notes">
            <Input.TextArea
              value={data.notes}
              onChange={(e) => update({ notes: e.target.value })}
              rows={3}
              placeholder="Optional notes about this instance..."
            />
          </Form.Item>
        </Form>
      ),
    },
    {
      title: 'Features',
      content: (
        <Space direction="vertical" size="large" style={{ width: '100%' }}>
          <Card size="small" title="Media Manager">
            <Space>
              <Switch checked={data.enableMedia} onChange={(v) => update({ enableMedia: v })} />
              <span>Video library, uploads, gallery, analytics</span>
            </Space>
          </Card>
          <Card size="small" title="Newsletter (Listmonk)">
            <Space>
              <Switch checked={data.enableListmonk} onChange={(v) => update({ enableListmonk: v })} />
              <span>Email newsletters, subscriber management</span>
            </Space>
          </Card>
          <Card size="small" title="Events (Gancio)">
            <Space>
              <Switch checked={data.enableGancio} onChange={(v) => update({ enableGancio: v })} />
              <span>Community events calendar, shift sync</span>
            </Space>
          </Card>
          <Card size="small" title="Chat (Rocket.Chat)">
            <Space>
              <Switch checked={data.enableChat} onChange={(v) => update({ enableChat: v })} />
              <span>Team communication, channels</span>
            </Space>
          </Card>
          <Card size="small" title="Monitoring">
            <Space>
              <Switch checked={data.enableMonitoring} onChange={(v) => update({ enableMonitoring: v })} />
              <span>Prometheus, Grafana, alerts</span>
            </Space>
          </Card>
          <Card size="small" title="Dev Tools">
            <Space>
              <Switch checked={data.enableDevTools} onChange={(v) => update({ enableDevTools: v })} />
              <span>Code Server, Gitea, n8n, Homepage, Excalidraw</span>
            </Space>
          </Card>
          <Card size="small" title="Payments (Stripe)">
            <Space>
              <Switch checked={data.enablePayments} onChange={(v) => update({ enablePayments: v })} />
              <span>Products, donations, subscriptions, ticketed events</span>
            </Space>
          </Card>
          <Card size="small" title="Video Conferencing (Jitsi Meet)">
            <Space direction="vertical" style={{ width: '100%' }}>
              <Space>
                <Switch checked={data.enableMeet} onChange={(v) => update({ enableMeet: v })} />
                <span>Self-hosted video calls, Rocket.Chat integration (4 containers)</span>
              </Space>
              {data.enableMeet && (
                <Input
                  value={data.jvbAdvertiseIp}
                  onChange={(e) => update({ jvbAdvertiseIp: e.target.value })}
                  placeholder="Public IP for JVB (e.g., 203.0.113.10)"
                  style={{ maxWidth: 400 }}
                  addonBefore="JVB IP"
                />
              )}
            </Space>
          </Card>
          <Card size="small" title="SMS Campaigns">
            <Space>
              <Switch checked={data.enableSms} onChange={(v) => update({ enableSms: v })} />
              <span>Termux-based SMS outreach (no additional containers)</span>
            </Space>
          </Card>
          <Card size="small" title="Social Connections">
            <Space>
              <Switch checked={data.enableSocial} onChange={(v) => update({ enableSocial: v })} />
              <span>Volunteer social features, friend connections (no additional containers)</span>
            </Space>
          </Card>
          <Card size="small" title="People CRM">
            <Space>
              <Switch checked={data.enablePeople} onChange={(v) => update({ enablePeople: v })} />
              <span>Unified people management, contact linking (no additional containers)</span>
            </Space>
          </Card>
          <Card size="small" title="Analytics & GeoIP">
            <Space>
              <Switch checked={data.enableAnalytics} onChange={(v) => update({ enableAnalytics: v })} />
              <span>Unified analytics dashboard, visitor geo-tracking</span>
            </Space>
          </Card>
        </Space>
      ),
    },
    {
      title: 'Email',
      content: (
        <Form layout="vertical">
          <Form.Item label="Email Mode">
            <Space>
              <Switch
                checked={data.emailTestMode}
                onChange={(v) => update({ emailTestMode: v })}
                checkedChildren="Test Mode (MailHog)"
                unCheckedChildren="Real SMTP"
              />
            </Space>
          </Form.Item>
          {!data.emailTestMode && (
            <>
              <Form.Item label="SMTP Host">
                <Input
                  value={data.smtpHost}
                  onChange={(e) => update({ smtpHost: e.target.value })}
                  placeholder="smtp.sendgrid.net"
                />
              </Form.Item>
              <Form.Item label="SMTP Port">
                <InputNumber
                  value={data.smtpPort}
                  onChange={(v) => update({ smtpPort: v || 587 })}
                  style={{ width: 120 }}
                />
              </Form.Item>
              <Form.Item label="SMTP User">
                <Input
                  value={data.smtpUser}
                  onChange={(e) => update({ smtpUser: e.target.value })}
                  placeholder="apikey"
                />
              </Form.Item>
              <Form.Item label="From Address">
                <Input
                  value={data.smtpFrom}
                  onChange={(e) => update({ smtpFrom: e.target.value })}
                  placeholder="noreply@betteredmonton.org"
                />
              </Form.Item>
            </>
          )}
        </Form>
      ),
    },
    {
      title: 'Tunnel',
      content: (() => {
        const domain = data.domain || 'example.org';
        const resourceRows = [
          { key: 'app', name: 'Admin + Public', domain: `app.${domain}`, target: 'nginx:80', required: true },
          { key: 'api', name: 'API', domain: `api.${domain}`, target: 'nginx:80', required: true },
          { key: 'root', name: 'Documentation (root)', domain: domain, target: 'nginx:80', required: true },
          { key: 'docs', name: 'Documentation', domain: `docs.${domain}`, target: 'nginx:80', required: false },
          { key: 'db', name: 'Data Browser (NocoDB)', domain: `db.${domain}`, target: 'nginx:80', required: false },
          ...(data.enableMedia ? [{ key: 'media', name: 'Media API', domain: `media.${domain}`, target: 'nginx:80', required: false }] : []),
          ...(data.enableListmonk ? [{ key: 'listmonk', name: 'Newsletter (Listmonk)', domain: `listmonk.${domain}`, target: 'nginx:80', required: false }] : []),
          ...(data.enableGancio ? [{ key: 'events', name: 'Events (Gancio)', domain: `events.${domain}`, target: 'nginx:80', required: false }] : []),
          ...(data.enableMonitoring ? [{ key: 'grafana', name: 'Grafana', domain: `grafana.${domain}`, target: 'nginx:80', required: false }] : []),
          ...(data.enableDevTools ? [
            { key: 'code', name: 'Code Server', domain: `code.${domain}`, target: 'nginx:80', required: false },
            { key: 'git', name: 'Gitea', domain: `git.${domain}`, target: 'nginx:80', required: false },
            { key: 'n8n', name: 'n8n', domain: `n8n.${domain}`, target: 'nginx:80', required: false },
          ] : []),
          ...(data.enableChat ? [{ key: 'chat', name: 'Chat (Rocket.Chat)', domain: `chat.${domain}`, target: 'nginx:80', required: false }] : []),
          ...(data.enableMeet ? [{ key: 'meet', name: 'Video Conferencing (Jitsi)', domain: `meet.${domain}`, target: 'nginx:80', required: false }] : []),
        ];

        return (
          <Space direction="vertical" size="large" style={{ width: '100%' }}>
            <Alert
              message="Pangolin Tunnel (Newt)"
              description="Enable to deploy a Newt container that connects this instance to your Pangolin server for external access. You'll need to create a site in your Pangolin dashboard first to get the credentials below."
              type="info"
              showIcon
            />
            <Card size="small" title="Enable Pangolin Tunnel">
              <Space>
                <Switch checked={data.enablePangolin} onChange={(v) => update({ enablePangolin: v })} />
                <span>Deploy Newt container for tunnel connectivity</span>
              </Space>
            </Card>
            {data.enablePangolin && (
              <>
                <Alert
                  type="info"
                  showIcon
                  message="Step 1: Create a Site in Pangolin"
                  description={
                    <div>
                      <ol style={{ marginLeft: 20, marginBottom: 0 }}>
                        <li>Log in to your Pangolin dashboard</li>
                        <li>Navigate to <Typography.Text strong>Sites</Typography.Text> → <Typography.Text strong>Create New Site</Typography.Text></li>
                        <li>Choose site type: <Typography.Text strong>Newt</Typography.Text></li>
                        <li>Enter a site name (e.g., <Typography.Text code>changemaker-{data.slug || 'my-instance'}</Typography.Text>)</li>
                        <li>Choose a subnet (e.g., <Typography.Text code>100.90.128.0/24</Typography.Text>)</li>
                        <li>Select an exit node (if using multi-node setup)</li>
                        <li>Click <Typography.Text strong>Create Site</Typography.Text></li>
                        <li>Copy the generated <Typography.Text strong>Newt ID</Typography.Text> and <Typography.Text strong>Newt Secret</Typography.Text> — enter them below</li>
                      </ol>
                    </div>
                  }
                />

                <Card size="small" title="Step 2: Enter Newt Credentials">
                  <Form layout="vertical" style={{ marginTop: 8 }}>
                    <Form.Item
                      label="Pangolin Endpoint"
                      required
                      help="The URL of your Pangolin server (e.g. https://pangolin.example.com)"
                    >
                      <Input
                        value={data.pangolinEndpoint}
                        onChange={(e) => update({ pangolinEndpoint: e.target.value })}
                        placeholder="https://pangolin.bnkserve.org"
                      />
                    </Form.Item>
                    <Form.Item
                      label="Newt ID"
                      required
                      help="Site ID from your Pangolin dashboard"
                    >
                      <Input
                        value={data.pangolinNewtId}
                        onChange={(e) => update({ pangolinNewtId: e.target.value })}
                        placeholder="lriruhzhlwl4xkr"
                      />
                    </Form.Item>
                    <Form.Item
                      label="Newt Secret"
                      required
                      help="Site secret from your Pangolin dashboard"
                      style={{ marginBottom: 0 }}
                    >
                      <Input.Password
                        value={data.pangolinNewtSecret}
                        onChange={(e) => update({ pangolinNewtSecret: e.target.value })}
                        placeholder="Enter your Newt secret"
                      />
                    </Form.Item>
                  </Form>
                </Card>

                <Alert
                  type="info"
                  showIcon
                  message="Step 3: Create Public HTTP Resources (after provisioning)"
                  description={
                    <div>
                      <Typography.Paragraph>
                        After the instance is provisioned and running, create an HTTP resource in your Pangolin dashboard for each service below.
                        Navigate to <Typography.Text strong>Resources</Typography.Text> → <Typography.Text strong>Add Resource</Typography.Text>.
                      </Typography.Paragraph>
                      <Table
                        dataSource={resourceRows}
                        size="small"
                        pagination={false}
                        style={{ marginTop: 8, marginBottom: 12 }}
                        columns={[
                          {
                            title: 'Service',
                            dataIndex: 'name',
                            key: 'name',
                            render: (name: string, record: typeof resourceRows[number]) => (
                              <Space>
                                <Typography.Text strong>{name}</Typography.Text>
                                {record.required && <Tag color="red">Required</Tag>}
                              </Space>
                            ),
                          },
                          {
                            title: 'Domain',
                            dataIndex: 'domain',
                            key: 'domain',
                            render: (d: string) => <Typography.Text code copyable>{d}</Typography.Text>,
                          },
                          {
                            title: 'Target',
                            dataIndex: 'target',
                            key: 'target',
                            render: (t: string) => <Typography.Text code>{t}</Typography.Text>,
                          },
                        ]}
                      />
                      <Typography.Paragraph strong style={{ marginBottom: 4 }}>For each resource:</Typography.Paragraph>
                      <ul style={{ marginBottom: 0, paddingLeft: 20 }}>
                        <li><Typography.Text strong>Protocol:</Typography.Text> HTTPS (SSL enabled)</li>
                        <li><Typography.Text strong>Target:</Typography.Text> nginx (all services route through nginx on port 80)</li>
                        <li><Typography.Text strong>Authentication:</Typography.Text> None — set as "Not Protected" for public access</li>
                      </ul>
                    </div>
                  }
                />
              </>
            )}
          </Space>
        );
      })(),
    },
    {
      title: 'Review',
      content: (
        <Space direction="vertical" size="large" style={{ width: '100%' }}>
          {error && <Alert message={error} type="error" showIcon closable onClose={() => setError(null)} />}
          <Descriptions bordered column={1} size="small">
            <Descriptions.Item label="Name">{data.name}</Descriptions.Item>
            <Descriptions.Item label="Slug">{data.slug}</Descriptions.Item>
            <Descriptions.Item label="Domain">{data.domain}</Descriptions.Item>
            <Descriptions.Item label="Admin Email">{data.adminEmail}</Descriptions.Item>
            <Descriptions.Item label="Email Mode">
              {data.emailTestMode ? 'Test (MailHog)' : `SMTP: ${data.smtpHost}:${data.smtpPort}`}
            </Descriptions.Item>
            <Descriptions.Item label="Features">
              <Space wrap>
                {data.enableMedia && <Tag color="blue">Media</Tag>}
                {data.enableListmonk && <Tag color="green">Newsletter</Tag>}
                {data.enableGancio && <Tag color="purple">Events</Tag>}
                {data.enableChat && <Tag color="orange">Chat</Tag>}
                {data.enableMonitoring && <Tag color="cyan">Monitoring</Tag>}
                {data.enableDevTools && <Tag color="geekblue">Dev Tools</Tag>}
                {data.enablePayments && <Tag color="gold">Payments</Tag>}
                {data.enableMeet && <Tag color="volcano">Jitsi Meet</Tag>}
                {data.enableSms && <Tag color="lime">SMS</Tag>}
                {data.enableSocial && <Tag color="magenta">Social</Tag>}
                {data.enablePeople && <Tag color="red">People CRM</Tag>}
                {!data.enableMedia && !data.enableListmonk && !data.enableGancio && !data.enableChat && !data.enableMonitoring && !data.enableDevTools && !data.enablePayments && !data.enableMeet && !data.enableSms && !data.enableSocial && !data.enablePeople && (
                  <Typography.Text type="secondary">Core only</Typography.Text>
                )}
              </Space>
            </Descriptions.Item>
            <Descriptions.Item label="Pangolin Tunnel">
              {data.enablePangolin ? (
                <Space direction="vertical" size={0}>
                  <Tag color="green">Enabled</Tag>
                  <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                    {data.pangolinEndpoint} &middot; Newt ID: {data.pangolinNewtId}
                  </Typography.Text>
                </Space>
              ) : (
                'Disabled'
              )}
            </Descriptions.Item>
          </Descriptions>
          <Alert
            message="Secrets will be auto-generated"
            description="Database passwords, JWT secrets, and encryption keys will be generated automatically and stored encrypted in the CCP database."
            type="info"
            showIcon
          />
        </Space>
      ),
    },
  ];

  // ─── Provisioning Progress View ──────────────────────────────────
  if (createdId && provisioningInstance) {
    const inst = provisioningInstance;
    const stepInfo = parseProvisioningStep(inst.statusMessage);
    const isDone = inst.status === 'RUNNING';
    const isError = inst.status === 'ERROR';

    if (isDone) {
      return (
        <Result
          status="success"
          title="Instance Ready!"
          subTitle={`${data.name} (${data.domain}) is running and ready to use.`}
          extra={[
            <Button key="view" type="primary" onClick={() => navigate(`/app/instances/${createdId}`)}>
              View Instance
            </Button>,
            <Button
              key="open"
              onClick={() => window.open(`https://app.${data.domain}`, '_blank')}
            >
              Open Site
            </Button>,
            <Button key="list" onClick={() => navigate('/app/instances')}>
              Back to List
            </Button>,
          ]}
        />
      );
    }

    if (isError) {
      return (
        <Result
          status="error"
          title="Provisioning Failed"
          subTitle={inst.statusMessage || 'An error occurred during provisioning.'}
          extra={[
            <Button key="retry" type="primary" onClick={handleRetryProvision}>
              Retry Provisioning
            </Button>,
            <Button key="view" onClick={() => navigate(`/app/instances/${createdId}`)}>
              View Instance Details
            </Button>,
            <Button key="list" onClick={() => navigate('/app/instances')}>
              Back to List
            </Button>,
          ]}
        />
      );
    }

    // Provisioning in progress
    const percent = stepInfo ? Math.round((stepInfo.current / stepInfo.total) * 100) : 0;
    return (
      <div style={{ maxWidth: 600, margin: '0 auto', textAlign: 'center', paddingTop: 40 }}>
        <SyncOutlined spin style={{ fontSize: 48, color: '#1890ff', marginBottom: 24 }} />
        <Typography.Title level={3}>Provisioning {data.name}...</Typography.Title>
        <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 24 }}>
          This may take several minutes. Please do not close this page.
        </Typography.Text>

        <Progress
          percent={percent}
          status="active"
          style={{ marginBottom: 16, maxWidth: 400, margin: '0 auto 16px' }}
        />

        {stepInfo && (
          <Card size="small" style={{ textAlign: 'left', maxWidth: 400, margin: '0 auto' }}>
            <Typography.Text strong>
              Step {stepInfo.current} of {stepInfo.total}
            </Typography.Text>
            <br />
            <Typography.Text type="secondary">{stepInfo.description}</Typography.Text>
          </Card>
        )}

        {!stepInfo && inst.statusMessage && (
          <Typography.Text type="secondary">{inst.statusMessage}</Typography.Text>
        )}

        <div style={{ marginTop: 24 }}>
          <Button onClick={() => navigate(`/app/instances/${createdId}`)}>
            View Instance Details
          </Button>
        </div>
      </div>
    );
  }

  const canProceed = () => {
    if (current === 0) {
      return data.name && data.slug && data.domain && data.adminEmail;
    }
    if (current === 3) {
      // Tunnel step: if Pangolin enabled, require all credentials
      if (data.enablePangolin) {
        return data.pangolinEndpoint && data.pangolinNewtId && data.pangolinNewtSecret;
      }
    }
    return true;
  };

  return (
    <div style={{ maxWidth: 800, margin: '0 auto' }}>
      <Typography.Title level={3}>Create New Instance</Typography.Title>

      <Steps current={current} items={steps.map((s) => ({ title: s.title }))} style={{ marginBottom: 32 }} />

      <Card>{steps[current].content}</Card>

      <div style={{ marginTop: 24, display: 'flex', justifyContent: 'space-between' }}>
        <Button disabled={current === 0} onClick={() => setCurrent(current - 1)}>
          Previous
        </Button>
        {current < steps.length - 1 ? (
          <Button type="primary" disabled={!canProceed()} onClick={() => setCurrent(current + 1)}>
            Next
          </Button>
        ) : (
          <Button type="primary" loading={creating} disabled={!canProceed()} onClick={handleCreate}>
            Create Instance
          </Button>
        )}
      </div>
    </div>
  );
}
