import { useEffect, useState } from 'react';
import {
  Typography,
  Card,
  Button,
  Row,
  Col,
  Progress,
  Segmented,
  Spin,
  Result,
  Grid,
  App,
  theme,
  Alert,
} from 'antd';
import {
  ScheduleOutlined,
  ClockCircleOutlined,
  EnvironmentOutlined,
  TeamOutlined,
  CheckCircleOutlined,
  SendOutlined,
  PlayCircleOutlined,
  VideoCameraOutlined,
} from '@ant-design/icons';
import { Link, useNavigate } from 'react-router-dom';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import { useCanvassStore } from '@/stores/canvass.store';
import FriendsAttendingBadge from '@/components/social/FriendsAttendingBadge';
import { getErrorMessage } from '@/utils/getErrorMessage';

const { Title, Text, Paragraph } = Typography;

interface VolunteerShift {
  id: string;
  title: string;
  description: string | null;
  date: string;
  startTime: string;
  endTime: string;
  location: string | null;
  maxVolunteers: number;
  currentVolunteers: number;
  status: 'OPEN' | 'FULL' | 'CANCELLED';
  isSignedUp: boolean;
  meeting?: { id: string; slug: string; isActive: boolean } | null;
}

interface MySignup {
  id: string;
  shiftId: string;
  shiftTitle: string;
  signupDate: string;
  shift: {
    id: string;
    title: string;
    description: string | null;
    date: string;
    startTime: string;
    endTime: string;
    location: string | null;
    maxVolunteers: number;
    currentVolunteers: number;
    status: string;
    meeting?: { id: string; slug: string; isActive: boolean } | null;
  };
}

type Tab = 'upcoming' | 'my-signups';

export default function VolunteerShiftsPage() {
  const { message, modal } = App.useApp();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const { token } = theme.useToken();
  const navigate = useNavigate();
  const activeSession = useCanvassStore((s) => s.session);

  const [tab, setTab] = useState<Tab>('upcoming');
  const [shifts, setShifts] = useState<VolunteerShift[]>([]);
  const [signups, setSignups] = useState<MySignup[]>([]);
  const [loading, setLoading] = useState(true);
  const [actionLoading, setActionLoading] = useState<string | null>(null);

  useEffect(() => {
    if (tab === 'upcoming') fetchUpcoming();
    else fetchSignups();
  }, [tab]); // eslint-disable-line react-hooks/exhaustive-deps

  const fetchUpcoming = async () => {
    setLoading(true);
    try {
      const { data } = await api.get<VolunteerShift[]>('/map/shifts/volunteer/upcoming');
      setShifts(data);
    } catch {
      message.error('Failed to load shifts');
    } finally {
      setLoading(false);
    }
  };

  const fetchSignups = async () => {
    setLoading(true);
    try {
      const { data } = await api.get<MySignup[]>('/map/shifts/volunteer/my-signups');
      setSignups(data);
    } catch {
      message.error('Failed to load signups');
    } finally {
      setLoading(false);
    }
  };

  const handleSignup = (shift: VolunteerShift) => {
    modal.confirm({
      title: 'Sign Up',
      content: (
        <div>
          <Text>Sign up for <Text strong>{shift.title}</Text>?</Text>
          <div style={{ marginTop: 8, padding: '8px 12px', background: 'rgba(255,255,255,0.04)', borderRadius: 6 }}>
            <div><ScheduleOutlined style={{ marginRight: 6 }} />{dayjs(shift.date).format('dddd, MMMM D, YYYY')}</div>
            <div><ClockCircleOutlined style={{ marginRight: 6 }} />{shift.startTime} — {shift.endTime}</div>
            {shift.location && <div><EnvironmentOutlined style={{ marginRight: 6 }} />{shift.location}</div>}
          </div>
        </div>
      ),
      okText: 'Sign Up',
      onOk: async () => {
        setActionLoading(shift.id);
        try {
          await api.post(`/map/shifts/volunteer/${shift.id}/signup`);
          message.success('Signed up successfully!');
          fetchUpcoming();
        } catch (err: unknown) {
          message.error(getErrorMessage(err, 'Failed to sign up'));
        } finally {
          setActionLoading(null);
        }
      },
    });
  };

  const handleCancel = (shiftId: string, shiftTitle: string) => {
    modal.confirm({
      title: 'Cancel Signup',
      content: `Cancel your signup for "${shiftTitle}"?`,
      okText: 'Cancel Signup',
      okButtonProps: { danger: true },
      onOk: async () => {
        setActionLoading(shiftId);
        try {
          await api.delete(`/map/shifts/volunteer/${shiftId}/signup`);
          message.success('Signup cancelled');
          if (tab === 'upcoming') fetchUpcoming();
          else fetchSignups();
        } catch (err: unknown) {
          message.error(getErrorMessage(err, 'Failed to cancel signup'));
        } finally {
          setActionLoading(null);
        }
      },
    });
  };

  const renderShiftCard = (shift: VolunteerShift) => {
    const spotsLeft = shift.maxVolunteers - shift.currentVolunteers;
    const isFull = shift.status === 'FULL' || spotsLeft <= 0;
    const pct = shift.maxVolunteers > 0
      ? Math.round((shift.currentVolunteers / shift.maxVolunteers) * 100)
      : 0;

    return (
      <Col key={shift.id} xs={24} sm={12}>
        <Card
          hoverable={!isFull && !shift.isSignedUp}
          style={{ height: '100%', opacity: isFull && !shift.isSignedUp ? 0.7 : 1 }}
          styles={{ body: { display: 'flex', flexDirection: 'column', height: '100%' } }}
        >
          <div style={{ flex: 1 }}>
            <Title level={5} style={{ margin: '0 0 8px 0' }}>{shift.title}</Title>
            <div style={{ marginBottom: 12 }}>
              <div style={{ marginBottom: 4 }}>
                <ScheduleOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                <Text>{dayjs(shift.date).format('ddd, MMM D, YYYY')}</Text>
              </div>
              <div style={{ marginBottom: 4 }}>
                <ClockCircleOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                <Text>{shift.startTime} — {shift.endTime}</Text>
              </div>
              {shift.location && (
                <div style={{ marginBottom: 4 }}>
                  <EnvironmentOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                  <Text>{shift.location}</Text>
                </div>
              )}
            </div>
            {shift.description && (
              <Paragraph type="secondary" ellipsis={{ rows: 2 }} style={{ marginBottom: 12 }}>
                {shift.description}
              </Paragraph>
            )}
            <div style={{ marginBottom: 12 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
                <Text type="secondary"><TeamOutlined style={{ marginRight: 4 }} />Volunteers</Text>
                <Text type="secondary">{shift.currentVolunteers}/{shift.maxVolunteers}</Text>
              </div>
              <Progress percent={pct} size="small" status={isFull ? 'exception' : 'active'} showInfo={false} />
              <Text type="secondary" style={{ fontSize: 12 }}>
                {isFull ? 'No spots available' : `${spotsLeft} spot${spotsLeft !== 1 ? 's' : ''} remaining`}
              </Text>
              <FriendsAttendingBadge shiftId={shift.id} />
            </div>
          </div>

          {shift.meeting?.isActive && (
            <Button
              type="default"
              block
              icon={<VideoCameraOutlined />}
              href={`/meet/${shift.meeting.slug}`}
              target="_blank"
              style={{ marginBottom: 8 }}
              size="small"
            >
              Join Briefing
            </Button>
          )}
          {shift.isSignedUp ? (
            <div>
              <Button type="primary" block icon={<CheckCircleOutlined />} style={{ marginBottom: 8 }}>
                Signed Up
              </Button>
              <Button
                type="text"
                danger
                block
                size="small"
                loading={actionLoading === shift.id}
                onClick={() => handleCancel(shift.id, shift.title)}
              >
                Cancel Signup
              </Button>
            </div>
          ) : (
            <Button
              type="primary"
              block
              disabled={isFull}
              loading={actionLoading === shift.id}
              onClick={() => handleSignup(shift)}
            >
              {isFull ? 'Shift Full' : 'Sign Up'}
            </Button>
          )}
        </Card>
      </Col>
    );
  };

  const renderSignupCard = (signup: MySignup) => {
    const { shift } = signup;
    return (
      <Col key={signup.id} xs={24} sm={12}>
        <Card style={{ height: '100%' }} styles={{ body: { display: 'flex', flexDirection: 'column', height: '100%' } }}>
          <div style={{ flex: 1 }}>
            <Title level={5} style={{ margin: '0 0 8px 0' }}>{shift.title}</Title>
            <div style={{ marginBottom: 12 }}>
              <div style={{ marginBottom: 4 }}>
                <ScheduleOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                <Text>{dayjs(shift.date).format('ddd, MMM D, YYYY')}</Text>
              </div>
              <div style={{ marginBottom: 4 }}>
                <ClockCircleOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                <Text>{shift.startTime} — {shift.endTime}</Text>
              </div>
              {shift.location && (
                <div style={{ marginBottom: 4 }}>
                  <EnvironmentOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
                  <Text>{shift.location}</Text>
                </div>
              )}
            </div>
            {shift.description && (
              <Paragraph type="secondary" ellipsis={{ rows: 2 }} style={{ marginBottom: 12 }}>
                {shift.description}
              </Paragraph>
            )}
          </div>
          {shift.meeting?.isActive && (
            <Button
              type="default"
              block
              icon={<VideoCameraOutlined />}
              href={`/meet/${shift.meeting.slug}`}
              target="_blank"
              style={{ marginBottom: 8 }}
              size="small"
            >
              Join Briefing
            </Button>
          )}
          <Button
            type="text"
            danger
            block
            loading={actionLoading === shift.id}
            onClick={() => handleCancel(shift.id, shift.title)}
          >
            Cancel Signup
          </Button>
        </Card>
      </Col>
    );
  };

  return (
    <div>
      <Typography.Title level={3} style={{ marginBottom: 16 }}>Shifts</Typography.Title>

      {/* Active session resume banner */}
      {activeSession?.cutId && (
        <Alert
          type="success"
          showIcon
          icon={<PlayCircleOutlined />}
          message="You have an active canvass session"
          action={
            <Button size="small" type="primary" onClick={() => navigate(`/volunteer/canvass/${activeSession.cutId}`)}>
              Resume
            </Button>
          }
          style={{ marginBottom: 16 }}
        />
      )}

      {/* Campaign context link */}
      <Card size="small" style={{ marginBottom: 16 }}>
        <SendOutlined style={{ marginRight: 8, color: token.colorPrimary }} />
        <Text type="secondary">See what you're working toward — </Text>
        <Link to="/campaigns" style={{ color: token.colorPrimary }}>View Campaigns</Link>
      </Card>

      <Segmented
        value={tab}
        onChange={(val) => setTab(val as Tab)}
        options={[
          { label: 'Upcoming', value: 'upcoming' },
          { label: 'My Signups', value: 'my-signups' },
        ]}
        block={isMobile}
        style={{ marginBottom: 24 }}
      />

      {loading ? (
        <div style={{ textAlign: 'center', padding: 60 }}><Spin size="large" /></div>
      ) : tab === 'upcoming' ? (
        shifts.length === 0 ? (
          <Result status="info" title="No Upcoming Shifts" subTitle="Check back later for volunteer opportunities." />
        ) : (
          <Row gutter={[16, 16]}>{shifts.map(renderShiftCard)}</Row>
        )
      ) : signups.length === 0 ? (
        <Result status="info" title="No Signups" subTitle="You haven't signed up for any shifts yet." />
      ) : (
        <Row gutter={[16, 16]}>{signups.map(renderSignupCard)}</Row>
      )}
    </div>
  );
}
