import { useState, useEffect } from 'react';
import { Tabs, Card, Form, Input, InputNumber, Button, Switch, Space, Typography, App, Alert } from 'antd';
import { CheckCircleOutlined } from '@ant-design/icons';
import { useOutletContext } from 'react-router-dom';
import { api } from '@/lib/api';
import type { PaymentSettings, AppOutletContext } from '@/types/api';

const { Text } = Typography;

function StripeSettingsTab() {
  const [settings, setSettings] = useState<PaymentSettings | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [form] = Form.useForm();
  const { message } = App.useApp();

  useEffect(() => {
    api.get('/payments/admin/settings')
      .then(({ data }) => { setSettings(data); form.setFieldsValue(data); })
      .catch(() => message.error('Failed to load settings'))
      .finally(() => setLoading(false));
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const handleSave = async () => {
    setSaving(true);
    try {
      const values = await form.validateFields();
      // Only send changed keys
      const toSend: Record<string, unknown> = {};
      for (const [k, v] of Object.entries(values)) {
        if (v !== undefined && v !== '') toSend[k] = v;
      }
      const { data } = await api.put('/payments/admin/settings', toSend);
      setSettings(data);
      message.success('Settings saved');
    } catch {
      message.error('Failed to save settings');
    } finally {
      setSaving(false);
    }
  };

  const handleTest = async () => {
    setTesting(true);
    try {
      const { data } = await api.post('/payments/admin/settings/test-connection');
      if (data.success) {
        message.success('Stripe connection verified!');
      } else {
        message.error(`Connection failed: ${data.message}`);
      }
    } catch {
      message.error('Failed to test connection');
    } finally {
      setTesting(false);
    }
  };

  if (loading) return null;

  return (
    <Form form={form} layout="vertical" style={{ maxWidth: 600 }}>
      <Text type="secondary" style={{ display: 'block', marginBottom: 16 }}>
        Connect your Stripe account to accept payments. You can find your API keys in the{' '}
        <a href="https://dashboard.stripe.com/apikeys" target="_blank" rel="noopener noreferrer">
          Stripe Dashboard → Developers → API keys
        </a>.
      </Text>
      <Form.Item
        name="stripeSecretKey"
        label="Secret Key"
        extra="Found in Stripe Dashboard → Developers → API keys. Starts with sk_test_ (test mode) or sk_live_ (production). Keep this secret — never expose it in frontend code."
      >
        <Input.Password placeholder={settings?.stripeSecretKey || 'sk_test_...'} />
      </Form.Item>
      <Form.Item
        name="stripePublishableKey"
        label="Publishable Key"
        extra="Found in the same API keys page. Starts with pk_test_ or pk_live_. This key is safe to include in frontend code."
      >
        <Input placeholder="pk_test_..." />
      </Form.Item>
      <Form.Item
        name="stripeWebhookSecret"
        label="Webhook Secret"
        extra={
          <span>
            Verifies that incoming Stripe events are authentic. To set up:
            go to Stripe Dashboard → Developers → Webhooks → Add endpoint,
            set the URL to <code>https://&lt;your-api-domain&gt;/api/payments/webhook</code>,
            and subscribe to these events: <code>checkout.session.completed</code>,{' '}
            <code>invoice.paid</code>, <code>invoice.payment_failed</code>,{' '}
            <code>customer.subscription.updated</code>, <code>customer.subscription.deleted</code>,{' '}
            <code>charge.refunded</code>.
            The signing secret (starts with whsec_) is shown after creating the endpoint.
            Optional for basic one-time payments, but required for subscriptions, recurring billing, and refund tracking.
          </span>
        }
      >
        <Input.Password placeholder={settings?.stripeWebhookSecret || 'whsec_...'} />
      </Form.Item>
      <Form.Item
        name="defaultCurrency"
        label="Default Currency"
        extra="ISO 4217 currency code in lowercase (e.g. cad, usd, eur)."
      >
        <Input placeholder="cad" style={{ width: 100 }} />
      </Form.Item>
      <Space>
        <Button type="primary" onClick={handleSave} loading={saving}>Save Settings</Button>
        <Button icon={<CheckCircleOutlined />} onClick={handleTest} loading={testing}>Test Connection</Button>
      </Space>
    </Form>
  );
}

function DonationSettingsTab() {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const { message } = App.useApp();

  useEffect(() => {
    api.get('/payments/admin/settings')
      .then(({ data }) => {
        form.setFieldsValue({
          ...data,
          donationMinimum: data.donationMinimum / 100,
          donationSuggestedAmountsStr: (data.donationSuggestedAmounts || []).map((v: number) => (v / 100).toFixed(2)).join(', '),
        });
      })
      .catch(() => message.error('Failed to load settings'))
      .finally(() => setLoading(false));
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const handleSave = async () => {
    setSaving(true);
    try {
      const values = await form.validateFields();
      const toSend: Record<string, unknown> = {};
      if (values.enableDonations !== undefined) toSend.enableDonations = values.enableDonations;
      if (values.donationMinimum) toSend.donationMinimum = Math.round(values.donationMinimum * 100);
      if (values.donationPageTitle) toSend.donationPageTitle = values.donationPageTitle;
      if (values.donationPageDescription !== undefined) toSend.donationPageDescription = values.donationPageDescription;
      if (values.thankYouMessage) toSend.thankYouMessage = values.thankYouMessage;
      if (values.donationSuggestedAmountsStr) {
        toSend.donationSuggestedAmounts = values.donationSuggestedAmountsStr
          .split(',')
          .map((s: string) => Math.round(parseFloat(s.trim()) * 100))
          .filter((n: number) => !isNaN(n) && n > 0);
      }
      await api.put('/payments/admin/settings', toSend);
      message.success('Donation settings saved');
    } catch {
      message.error('Failed to save');
    } finally {
      setSaving(false);
    }
  };

  if (loading) return null;

  return (
    <Form form={form} layout="vertical" style={{ maxWidth: 600 }}>
      <Alert
        type="info"
        showIcon
        message="These are default donation settings. Create individual donation pages with per-page configuration under Payments → Donation Pages."
        style={{ marginBottom: 16 }}
      />
      <Form.Item name="enableDonations" label="Enable Donations" valuePropName="checked">
        <Switch />
      </Form.Item>
      <Form.Item name="donationMinimum" label="Minimum Donation (CAD)">
        <InputNumber min={1} step={0.5} prefix="$" style={{ width: '100%' }} />
      </Form.Item>
      <Form.Item name="donationSuggestedAmountsStr" label="Suggested Amounts (comma-separated, in dollars)">
        <Input placeholder="10.00, 25.00, 50.00, 100.00" />
      </Form.Item>
      <Form.Item name="donationPageTitle" label="Donation Page Title">
        <Input />
      </Form.Item>
      <Form.Item name="donationPageDescription" label="Donation Page Description">
        <Input.TextArea rows={3} />
      </Form.Item>
      <Form.Item name="thankYouMessage" label="Thank You Message">
        <Input.TextArea rows={3} />
      </Form.Item>
      <Button type="primary" onClick={handleSave} loading={saving}>Save Donation Settings</Button>
    </Form>
  );
}

export default function PaymentSettingsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();

  useEffect(() => {
    setPageHeader({ title: 'Payment Settings' });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  return (
    <div>
      <Card>
        <Tabs
          items={[
            { key: 'stripe', label: 'Stripe', children: <StripeSettingsTab /> },
            { key: 'donations', label: 'Donations', children: <DonationSettingsTab /> },
          ]}
        />
      </Card>
    </div>
  );
}
