"use client";

import { useReducer, useEffect } from "react";
import { sendStopBlast } from "@/actions/communications/stop-blast";
import {
  getStopMessagingData,
  type StopOrder,
  type StopBlastMessage,
} from "@/actions/communications/stop-messaging";

type Audience = "all" | "pending" | "picked_up";
type Channel = "sms" | "email" | "both";

type LoadData = {
  orders: StopOrder[];
  messages: StopBlastMessage[];
  error: string | null;
  loadingOrders: boolean;
  loadingMessages: boolean;
};

type State = {
  audience: Audience;
  channel: Channel;
  subject: string;
  body: string;
  sending: boolean;
  confirm: string | null;
  loadData: LoadData;
};

type Action =
  | { type: "SET_AUDIENCE"; value: Audience }
  | { type: "SET_CHANNEL"; value: Channel }
  | { type: "SET_SUBJECT"; value: string }
  | { type: "SET_BODY"; value: string }
  | { type: "SET_SENDING"; value: boolean }
  | { type: "SET_CONFIRM"; value: string | null }
  | { type: "SET_ERROR"; value: string | null }
  | { type: "SEND_START" }
  | { type: "SEND_SUCCESS"; messagesLogged: number }
  | { type: "SEND_FAIL"; error: string }
  | { type: "LOAD_RESET" }
  | { type: "LOAD_SUCCESS"; orders: StopOrder[]; messages: StopBlastMessage[] }
  | { type: "LOAD_FAIL"; error: string }
  | { type: "REFRESH_MESSAGES_START" }
  | { type: "REFRESH_MESSAGES_SUCCESS"; messages: StopBlastMessage[] }
  | { type: "REFRESH_MESSAGES_FAIL" };

const initialState: State = {
  audience: "pending",
  channel: "sms",
  subject: "",
  body: "",
  sending: false,
  confirm: null,
  loadData: {
    orders: [],
    messages: [],
    error: null,
    loadingOrders: true,
    loadingMessages: true,
  },
};

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_AUDIENCE":
      return { ...state, audience: action.value };
    case "SET_CHANNEL":
      return { ...state, channel: action.value };
    case "SET_SUBJECT":
      return { ...state, subject: action.value };
    case "SET_BODY":
      return { ...state, body: action.value };
    case "SET_SENDING":
      return { ...state, sending: action.value };
    case "SET_CONFIRM":
      return { ...state, confirm: action.value };
    case "SET_ERROR":
      return {
        ...state,
        loadData: { ...state.loadData, error: action.value },
      };
    case "SEND_START":
      return {
        ...state,
        sending: true,
        confirm: null,
        loadData: { ...state.loadData, error: null },
      };
    case "SEND_SUCCESS":
      return {
        ...state,
        sending: false,
        subject: "",
        body: "",
        confirm: `Blast sent — ${action.messagesLogged} message${action.messagesLogged !== 1 ? "s" : ""} logged via campaign.`,
      };
    case "SEND_FAIL":
      return {
        ...state,
        sending: false,
        loadData: { ...state.loadData, error: action.error },
      };
    case "LOAD_RESET":
      return {
        ...state,
        loadData: {
          orders: [],
          messages: [],
          error: null,
          loadingOrders: true,
          loadingMessages: true,
        },
      };
    case "LOAD_SUCCESS":
      return {
        ...state,
        loadData: {
          ...state.loadData,
          orders: action.orders,
          messages: action.messages,
          loadingOrders: false,
          loadingMessages: false,
        },
      };
    case "LOAD_FAIL":
      return {
        ...state,
        loadData: {
          ...state.loadData,
          error: action.error,
          loadingOrders: false,
          loadingMessages: false,
        },
      };
    case "REFRESH_MESSAGES_START":
      return {
        ...state,
        loadData: { ...state.loadData, loadingMessages: true },
      };
    case "REFRESH_MESSAGES_SUCCESS":
      return {
        ...state,
        loadData: {
          ...state.loadData,
          loadingMessages: false,
          messages: action.messages,
        },
      };
    case "REFRESH_MESSAGES_FAIL":
      return {
        ...state,
        loadData: { ...state.loadData, loadingMessages: false },
      };
  }
}

type MessageCustomersSectionProps = {
  stopId: string;
  brandId?: string;
};

export default function MessageCustomersSection({
  stopId,
  brandId,
}: MessageCustomersSectionProps) {
  const [state, dispatch] = useReducer(reducer, initialState);
  const { audience, channel, subject, body, sending, confirm, loadData } = state;
  const { orders, messages, error, loadingOrders, loadingMessages } = loadData;

  // When (stopId, brandId) changes, reset to the loading state so users
  // don't see stale "loaded" data from the previous stop.
  useEffect(() => {
    dispatch({ type: "LOAD_RESET" });
  }, [stopId, brandId]);

  useEffect(() => {
    let cancelled = false;
    void (async () => {
      const res = await getStopMessagingData({ stopId, brandId });
      if (cancelled) return;
      if (res.success) {
        dispatch({
          type: "LOAD_SUCCESS",
          orders: res.orders,
          messages: res.messages,
        });
      } else {
        dispatch({ type: "LOAD_FAIL", error: res.error });
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [stopId, brandId]);

  const allOrders = orders;
  const pendingOrders = orders.filter((o) => !o.pickup_complete);
  const pickedUpOrders = orders.filter((o) => o.pickup_complete);

  const filteredOrders = (() => {
    if (audience === "pending") return pendingOrders;
    if (audience === "picked_up") return pickedUpOrders;
    return allOrders;
  })();

  const recipients = filteredOrders.filter((o) => {
    if (channel === "sms") return o.customer_phone;
    if (channel === "email") return o.customer_email;
    return o.customer_phone || o.customer_email;
  });

  const showSubject = channel === "email" || channel === "both";

  async function handleSend(e: React.FormEvent) {
    e.preventDefault();
    if (!body.trim()) return;
    if (showSubject && !subject.trim()) {
      dispatch({
        type: "SET_ERROR",
        value: "Subject is required for email or both.",
      });
      return;
    }
    if (!brandId) {
      dispatch({
        type: "SET_ERROR",
        value: "Brand ID not available.",
      });
      return;
    }

    dispatch({ type: "SEND_START" });

    const result = await sendStopBlast({
      stopId,
      brandId,
      channel,
      subject: showSubject ? subject : undefined,
      body,
      audience,
    });

    if (!result.success) {
      dispatch({
        type: "SEND_FAIL",
        error: result.error ?? "Failed to send blast",
      });
      return;
    }
    dispatch({
      type: "SEND_SUCCESS",
      messagesLogged: result.messages_logged,
    });

    // Refresh the message log
    dispatch({ type: "REFRESH_MESSAGES_START" });
    const res = await getStopMessagingData({ stopId, brandId });
    if (res.success) {
      dispatch({ type: "REFRESH_MESSAGES_SUCCESS", messages: res.messages });
    } else {
      dispatch({ type: "REFRESH_MESSAGES_FAIL" });
    }
  }

  return (
    <div className="space-y-6">
      {error && (
        <div className="rounded-xl bg-red-900/30 p-4 text-sm text-red-400">
          {error}
        </div>
      )}

      {confirm && (
        <div className="rounded-xl bg-green-900/30 p-4 text-sm text-green-400">
          {confirm}
        </div>
      )}

      {loadingOrders ? (
        <p className="text-sm text-zinc-500">Loading orders...</p>
      ) : orders.length === 0 ? (
        <p className="text-sm text-zinc-500">No orders for this stop yet.</p>
      ) : (
        <MessageForm
          audience={audience}
          channel={channel}
          subject={subject}
          body={body}
          sending={sending}
          allOrders={allOrders}
          pendingOrders={pendingOrders}
          pickedUpOrders={pickedUpOrders}
          recipientsLength={recipients.length}
          showSubject={showSubject}
          onSelectAudience={(a) => dispatch({ type: "SET_AUDIENCE", value: a })}
          onSelectChannel={(ch) => dispatch({ type: "SET_CHANNEL", value: ch })}
          onSubjectChange={(v) => dispatch({ type: "SET_SUBJECT", value: v })}
          onBodyChange={(v) => dispatch({ type: "SET_BODY", value: v })}
          onSubmit={handleSend}
        />
      )}

      {/* Recent message history */}
      {!loadingMessages && messages.length > 0 && (
        <MessageHistory messages={messages} />
      )}
    </div>
  );
}

type MessageFormProps = {
  audience: Audience;
  channel: Channel;
  subject: string;
  body: string;
  sending: boolean;
  allOrders: StopOrder[];
  pendingOrders: StopOrder[];
  pickedUpOrders: StopOrder[];
  recipientsLength: number;
  showSubject: boolean;
  onSelectAudience: (a: Audience) => void;
  onSelectChannel: (ch: Channel) => void;
  onSubjectChange: (v: string) => void;
  onBodyChange: (v: string) => void;
  onSubmit: (e: React.FormEvent) => void;
};

function MessageForm({
  audience,
  channel,
  subject,
  body,
  sending,
  allOrders,
  pendingOrders,
  pickedUpOrders,
  recipientsLength,
  showSubject,
  onSelectAudience,
  onSelectChannel,
  onSubjectChange,
  onBodyChange,
  onSubmit,
}: MessageFormProps) {
  return (
    <>
      {/* Audience selector */}
      <div>
        <label className="mb-2 block text-sm font-medium text-zinc-300" htmlFor="fld-audience---recipientslength-with-contact">
          Audience —{" "}
          <span className="text-zinc-500">
            {recipientsLength} with contact info
          </span>
        </label>
        <div className="flex gap-2">
          {(["all", "pending", "picked_up"] as const).map((a) => {
            const count =
              a === "all"
                ? allOrders.length
                : a === "pending"
                ? pendingOrders.length
                : pickedUpOrders.length;
            return (
              <button type="button"
                key={a}
                onClick={() => onSelectAudience(a)}
                className={`flex-1 rounded-xl px-3 py-2 text-sm font-medium capitalize transition-colors ${
                  audience === a
                    ? "bg-slate-900 text-white"
                    : "bg-zinc-950 text-zinc-400 hover:bg-slate-200"
                }`}
              >
                {a.replace("_", " ")} ({count})
              </button>
            );
          })}
        </div>
      </div>

      {/* Channel selector */}
      <div>
        <label className="mb-2 block text-sm font-medium text-zinc-300" htmlFor="fld-channel">
          Channel
        </label>
        <div className="flex gap-2">
          {(["sms", "email", "both"] as const).map((ch) => (
            <button type="button"
              key={ch}
              onClick={() => onSelectChannel(ch)}
              className={`flex-1 rounded-xl px-3 py-2 text-sm font-medium transition-colors ${
                channel === ch
                  ? "bg-slate-900 text-white"
                  : "bg-zinc-950 text-zinc-400 hover:bg-slate-200"
              }`}
            >
              {ch === "sms" ? "📱 SMS" : ch === "email" ? "✉️ Email" : "📱+✉️ Both"}
            </button>
          ))}
        </div>
      </div>

      <form onSubmit={onSubmit} className="space-y-4">
        {showSubject && (
          <div>
            <label htmlFor="fld-1-subject"  className="mb-1 block text-sm font-medium text-zinc-300">Subject</label>
            <input id="fld-1-subject"  aria-label="Important Update About Your Pickup"
              type="text"
              value={subject}
              onChange={(e) => onSubjectChange(e.target.value)}
              placeholder="Important update about your pickup"
              className="w-full rounded-xl border border-zinc-600 bg-zinc-900 px-4 py-3 text-base outline-none focus:border-slate-900"
            />
          </div>
        )}

        <div>
          <label htmlFor="fld-2-message"  className="mb-1 block text-sm font-medium text-zinc-300">Message</label>
          <textarea id="fld-2-message"  aria-label="Type Your Message Here..."
            value={body}
            onChange={(e) => onBodyChange(e.target.value)}
            rows={4}
            className="w-full rounded-xl border border-zinc-600 bg-zinc-900 px-4 py-3 text-base outline-none focus:border-slate-900"
            placeholder="Type your message here..."
          />
          <p className="mt-1 text-xs text-slate-400">{body.length} characters</p>
        </div>

        <button
          type="submit"
          disabled={!body.trim() || recipientsLength === 0 || sending}
          className="w-full rounded-xl bg-slate-900 px-6 py-4 text-lg font-bold text-white disabled:opacity-50"
        >
          {sending
            ? "Sending..."
            : `Send to ${recipientsLength} customer${recipientsLength !== 1 ? "s" : ""}`}
        </button>
      </form>
    </>
  );
}

function MessageHistory({ messages }: { messages: StopBlastMessage[] }) {
  return (
    <div>
      <p className="mb-3 text-sm font-medium text-zinc-300">
        Recent Messages
      </p>
      <div className="space-y-2">
        {messages.map((msg) => (
          <div
            key={msg.id}
            className="rounded-xl border border-zinc-800 bg-slate-50 px-4 py-3"
          >
            <div className="flex items-start justify-between gap-3">
              <div className="min-w-0 flex-1">
                <p className="font-medium text-zinc-100">
                  {msg.type.toUpperCase()}{" "}
                  {msg.subject && <span className="text-zinc-500">— {msg.subject}</span>}
                </p>
                <p className="mt-1 truncate text-sm text-zinc-400">{msg.body}</p>
                <p className="mt-1 text-xs text-slate-400">
                  {new Date(msg.created_at).toLocaleString()} ·{" "}
                  {msg.message_recipients?.length ?? 0} recipients
                </p>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}