import { useEffect, useState } from 'react';
import { Drawer, Form, Input, Button, Spin, Typography, Space, App } from 'antd';
import type { SupportLevel, UserRole } from '@/types/api';
import { SUPPORT_LEVEL_LABELS, SUPPORT_LEVEL_COLORS, MAP_ADMIN_ROLES } from '@/types/api';
import type { VisitOutcome } from '@/types/canvass';
import { VISIT_OUTCOME_LABELS, VISIT_OUTCOME_COLORS } from '@/types/canvass';
import { useCanvassStore } from '@/stores/canvass.store';
import { useTrackingStore } from '@/stores/tracking.store';

interface AddLocationDrawerProps {
  open: boolean;
  onClose: () => void;
  lat: number | null;
  lng: number | null;
  userRole: UserRole;
  sessionId?: string;
  shiftId?: string;
  zIndex?: number;
}

const outcomeKeys: VisitOutcome[] = [
  'SPOKE_WITH',
  'NOT_HOME',
  'REFUSED',
  'LEFT_LITERATURE',
  'COME_BACK_LATER',
  'MOVED',
  'ALREADY_VOTED',
];

const supportLevelKeys: SupportLevel[] = ['LEVEL_1', 'LEVEL_2', 'LEVEL_3', 'LEVEL_4'];

export default function AddLocationDrawer({
  open,
  onClose,
  lat,
  lng,
  userRole,
  sessionId: _sessionId,
  shiftId: _shiftId,
  zIndex = 1000,
}: AddLocationDrawerProps) {
  const [form] = Form.useForm();
  const { message } = App.useApp();
  const { addLocation, reverseGeocode } = useCanvassStore();
  const [loading, setLoading] = useState(false);
  const [geocoding, setGeocoding] = useState(false);
  const [outcome, setOutcome] = useState<VisitOutcome | null>(null);
  const [supportLevel, setSupportLevel] = useState<SupportLevel | undefined>(undefined);
  const [signRequested, setSignRequested] = useState(false);
  const [signSize, setSignSize] = useState<string | undefined>(undefined);
  const [notes, setNotes] = useState('');

  const isTemp = userRole === 'TEMP';
  const isAdmin = MAP_ADMIN_ROLES.includes(userRole);
  const showDetailFields = !isTemp;

  useEffect(() => {
    if (!open || lat === null || lng === null) return;
    form.resetFields();
    form.setFieldsValue({ address: '' });
    setOutcome(null);
    setSupportLevel(undefined);
    setSignRequested(false);
    setSignSize(undefined);
    setNotes('');

    // Reverse geocode the coordinates
    setGeocoding(true);
    reverseGeocode(lat, lng)
      .then((result) => {
        form.setFieldsValue({ address: result.address });
      })
      .catch(() => {
        // Non-critical — user can type address manually
      })
      .finally(() => setGeocoding(false));
  }, [open, lat, lng, form, reverseGeocode]);

  const handleSubmit = async () => {
    if (lat === null || lng === null) return;
    if (!outcome) {
      message.warning('Select an outcome');
      return;
    }
    try {
      const values = await form.validateFields();
      setLoading(true);

      // Build location data — include support level + sign from visit fields
      const locationData: Record<string, unknown> = {
        ...values,
        latitude: lat,
        longitude: lng,
      };
      if (showDetailFields && supportLevel) locationData.supportLevel = supportLevel;
      if (showDetailFields && signRequested) {
        locationData.sign = true;
        if (signSize) locationData.signSize = signSize;
      }
      if (showDetailFields && notes) locationData.notes = notes;

      // Create location
      await addLocation(locationData);

      // Track event point for location added
      useTrackingStore.getState().addEventPoint(lat, lng, 'LOCATION_ADDED');

      // TODO: Record visit on the new address
      // Need to get addressId from created location (returned from addLocation above)
      // For now, just add the location - visit can be recorded separately

      message.success('Location added successfully');
      onClose();
    } catch {
      message.error('Failed to add location');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Drawer
      placement="bottom"
      open={open}
      onClose={onClose}
      height="auto"
      zIndex={zIndex}
      forceRender
      styles={{
        body: { padding: '12px 16px', maxHeight: '70vh', overflow: 'auto' },
      }}
      title="New Door"
      extra={
        <Button type="primary" size="small" onClick={handleSubmit} loading={loading} disabled={!outcome}>
          Save
        </Button>
      }
    >
      {geocoding && (
        <div style={{ textAlign: 'center', padding: 20 }}>
          <Spin size="small" />
          <Typography.Text type="secondary" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>
            Looking up address...
          </Typography.Text>
        </div>
      )}

      <div style={{ display: geocoding ? 'none' : undefined }}>
          <Form form={form} layout="vertical" size="small">
            <Form.Item
              name="address"
              label="Address"
              rules={[{ required: true, message: 'Address is required' }]}
            >
              <Input />
            </Form.Item>
            <Form.Item name="unitNumber" label="Unit / Apt #">
              <Input />
            </Form.Item>

            {isAdmin && (
              <>
                <Form.Item name="firstName" label="First Name">
                  <Input />
                </Form.Item>
                <Form.Item name="lastName" label="Last Name">
                  <Input />
                </Form.Item>
                <Form.Item name="email" label="Email">
                  <Input type="email" />
                </Form.Item>
                <Form.Item name="phone" label="Phone">
                  <Input />
                </Form.Item>
              </>
            )}
          </Form>

          {/* Outcome — always visible */}
          <Typography.Text strong style={{ display: 'block', marginBottom: 6, fontSize: 13 }}>
            Outcome
          </Typography.Text>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 12 }}>
            {outcomeKeys.map((key) => {
              const color = VISIT_OUTCOME_COLORS[key];
              const selected = outcome === key;
              return (
                <Button
                  key={key}
                  size="middle"
                  type={selected ? 'primary' : 'default'}
                  style={{
                    borderColor: color,
                    background: selected ? color : 'transparent',
                    color: selected ? '#fff' : color,
                    fontSize: 12,
                  }}
                  onClick={() => setOutcome(key)}
                >
                  {VISIT_OUTCOME_LABELS[key]}
                </Button>
              );
            })}
          </div>

          {/* Support level — non-TEMP, only when SPOKE_WITH */}
          {showDetailFields && outcome === 'SPOKE_WITH' && (
            <>
              <Typography.Text strong style={{ display: 'block', marginBottom: 6, fontSize: 13 }}>
                Support Level
              </Typography.Text>
              <Space style={{ marginBottom: 12 }}>
                {supportLevelKeys.map((key) => (
                  <Button
                    key={key}
                    shape="circle"
                    size="large"
                    type={supportLevel === key ? 'primary' : 'default'}
                    style={{
                      width: 44,
                      height: 44,
                      background: supportLevel === key ? SUPPORT_LEVEL_COLORS[key] : undefined,
                      borderColor: SUPPORT_LEVEL_COLORS[key],
                      color: supportLevel === key ? '#fff' : SUPPORT_LEVEL_COLORS[key],
                      fontWeight: 700,
                    }}
                    onClick={() => setSupportLevel(supportLevel === key ? undefined : key)}
                  >
                    {key.replace('LEVEL_', '')}
                  </Button>
                ))}
              </Space>
              {supportLevel && (
                <div style={{ marginBottom: 4 }}>
                  <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                    {SUPPORT_LEVEL_LABELS[supportLevel]}
                  </Typography.Text>
                </div>
              )}

              <Typography.Text strong style={{ display: 'block', marginBottom: 6, fontSize: 13 }}>
                Sign
              </Typography.Text>
              <Space style={{ marginBottom: 12 }}>
                <Button
                  type={signRequested ? 'primary' : 'default'}
                  onClick={() => { setSignRequested(!signRequested); if (signRequested) setSignSize(undefined); }}
                >
                  {signRequested ? 'Yes' : 'No Sign'}
                </Button>
                {signRequested && (
                  <>
                    {(['Regular', 'Large', 'Unsure'] as const).map((size) => (
                      <Button
                        key={size}
                        type={signSize === size ? 'primary' : 'default'}
                        onClick={() => setSignSize(size)}
                        size="small"
                      >
                        {size}
                      </Button>
                    ))}
                  </>
                )}
              </Space>
            </>
          )}

          {/* Notes — non-TEMP */}
          {showDetailFields && (
            <>
              <Typography.Text strong style={{ display: 'block', marginBottom: 6, fontSize: 13 }}>
                Notes
              </Typography.Text>
              <Input.TextArea
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                rows={2}
                placeholder="Optional notes..."
                style={{ marginBottom: 12 }}
              />
            </>
          )}
      </div>
    </Drawer>
  );
}
